C套接字阻塞调用

时间:2017-08-11 13:00:20

标签: c multithreading sockets nonblocking

我想知道socket对阻塞和非阻塞操作的行为。当套接字阻塞模式改变时,套接字上阻塞的线程会发生什么?这是场景; thread1(T1)创建一个UDP套接字和

fd = socket(AF_INET , SOCK_DGRAM, 0);

T1等待(休眠)接收

recv(fd, buf , sizeof(buf) , 0);

和thread2(T2)在套接字接收任何数据之前将套接字模式更改为非阻塞

fcntl(fd, F_SETFL, O_NONBLOCK);

T1会发生什么?它是否发出信号/醒来,因为套接字不再阻塞?

2 个答案:

答案 0 :(得分:8)

行为字面上未指定:fcntl不需要取消阻止任何线程。

Linux just sets the flag in the file description struct file and returns without unblocking any blocked threads.

recv中阻止的线程只能在以下情况下运行:

  • 要阅读的数据可用;
  • 或检测到文件描述符上的错误条件(FIN / RST,套接字读取超时,TCP保持活动失败,文件描述符由另一个线程close d) ;
  • 或收到信号且信号处理不包括SA_RESTART;
  • pthread_cancel领导。

您尝试更改另一个线程的文件描述符的标志这一事实表明您的设计需要审核。理想情况下,线程不得共享任何数据,也不得互相攻击彼此的状态,而应使用消息传递来相互通信。

答案 1 :(得分:0)

未阻止线程(由于在阻止模式下读取而未阻止)将表现得好像它始终是非阻塞模式。

阅读recv(2) manual page

  

如果套接字上没有可用的消息,并且套接字是非阻塞的,则返回值-1和外部          变量errno设置为EAGAIN或EWOULDBLOCK。

阻止线程(在阻止模式下读取时被阻止),然后更改为非阻塞。 正如@Maxim共享未唤醒线程的函数代码所指出的那样,阻塞的线程只会在写入完成后被唤醒(数据可用)。