如何唤醒socket被阻塞的函数

发表于:2013-2-18 10:27

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:懒惰的肥兔    来源:51Testing软件测试网采编

  那么,如果把 pthread_join 换成 pthread_cancel 呢?结果是一样的,虽然主进程退出了,但依然无法让 service 线程正常退出。那么,该如何才能正常退出 recvfrom 的阻塞呢?

  网上搜了一下,可以考虑使用 shutdown 函数。

  1. //shutdown函数原型为:  
  2. #include <sys/socket.h>  
  3. int shutdown(int s, int how);  
  4.   
  5. //shutdown() 可以对套接字的关闭进行更细致的控制,它允许对套接字进行单向关闭或全部禁止。  
  6. //参数 s 为待关闭的套接字描述符。  
  7. //参数 how 指定了关闭方式,具体取值如下:  
  8. //SHUT_RD : 将连接上的读通道关闭,此后进程将不能再接收到任何数据,接收缓冲区中还未被读取的数据也将被丢弃,但仍然可以在该套接字上发送数据。  
  9. //SHUT_WR : 将连接上的写通道关闭,此后进程将不能再发送任何数据,发送缓冲区中还未被发送的数据也将被丢弃,但仍然可以在该套接字上接收数据。  
  10. //SHUT_RDWR : 读、写通道都将被关闭。  
  11. //执行成功返回 0,出错则返回 -1,错误代码存入 errno 中。

  可以测试一下,我们在上述代码的pthread_join前面加上一句:shutdown(fd,SHUT_RDWR); 然后再编译调试,结果如下:

  可以看到,Service服务线程已经正常退出了。进一步测试,如果只是shutdown写通道或者只shutdown读通道呢?

  经过测试可以发现,如果只关闭写通道 shutdown(fd,SHUT_WR);服务线程依然无法正常退出,而如果只关闭读通道 shutdown(fd,SHUT_RD),则服务线程正常退出了。分析如下:因为recvfrom在fd的读通道等待列表中,因此必须关闭读通道时才能将recvfrom阻塞唤醒。

  那么,为啥shutdown就可以使得recvfrom退出阻塞,而close却不能呢?

  我的理解如下:shutdown破坏了socket连接的读写通道,导致读写阻塞的socket函数被唤醒,而close函数只是做了关闭连接释放socket资源的操作,却并没有进行读写通道的清理工作,从而无法成功唤醒读写函数的阻塞。(期待高手给出更深层次的解释)

  进一步,那么,解决这一问题,还有其他的什么办法没有?

  下面我简单地罗列一下网上搜到的可行的一些方法,以后有时间再深入研究:

  1、设置socket发送/接收超时

  2、使用非阻塞方式,异步socket模型

  3、其他方式,欢迎大家补充。

  文章就写到这里了,欢迎大家交流。

22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号