当前位置: 技术问答>linux和unix
socket read阻塞:一个线程关闭另一个线程错误
来源: 互联网 发布时间:2016-08-30
本文导语: 本帖最后由 yangzhifu 于 2010-05-27 12:01:31 编辑 机制:两个线程,一个线程通过关闭socket来让另外一个线程退出,具体如下: service线程,负责接受数据,当为-1的时候退出,当接受到心跳包的时候,更新时间,代码如下: ...
service线程,负责接受数据,当为-1的时候退出,当接受到心跳包的时候,更新时间,代码如下:
time_t activetime;
while(signalquit)
{
memset(curr_pack,0,sizeof(serv_pack));
nrecv = read(my_id,(unsigned char *)curr_pack,16);
if(nrecv == -1 )
{
break;
}
else
{
memcpy(&keep_alive,curr_pack,sizeof(keep_alive)); //心跳包
if (keep_alive == -1 )
{
activetime = time((time_t *)NULL);
continue;
}
}
}
close_sock(my_id);
clear_by_sock_id(my_id);
free(curr_pack);
}
tiem_active线程,如果超时,那么关闭socket
void time_activeThrFxn(void )
{
time_t cur_time;
if(DEBUG)
printf("Init active_time thread! n");
while(signalquit)
{
if (cur_time - activetime > DELAYTIMENUM){
close_sock(my_id);
}
}
sleep(DELAYTIMENUM/12);
}
}
问题:在socket关闭后service线程的read函数一直阻塞,不能退出
为什么socket关闭后read还会一直阻塞呢?怎么没有退出,有什么解决方法?
|
这里应该调用socket的标准接口recv,他会判断socket关闭时并返回-1.
还有一点要注意:就是尽量不考虑外部来关闭线程,所以使用pthread_cancel要谨慎.
还有一点要注意:就是尽量不考虑外部来关闭线程,所以使用pthread_cancel要谨慎.
|
你可以用 int pthread_cancel(pthread_t thread);
取消掉 目标线程。
取消掉 目标线程。
|
另外,你可以使用 select 模型类避免阻塞的问题。
nrecv = read(my_id,(unsigned char *)curr_pack,16);
|
貌似标准并没有定义描述符关闭后再 在其上读操作的结果,照理是两种,一种出错返回-1,另一种就是阻塞,因为发来的数据找不到相应的描述符,所以虽然已经关闭描述符,但是仍然可以引用,但是套接字协议认为已经关闭,肯定不会再把数据发到该描述符