我想知道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会发生什么?它是否发出信号/醒来,因为套接字不再阻塞?
答案 0 :(得分:8)
行为字面上未指定:fcntl
不需要取消阻止任何线程。
recv
中阻止已的线程只能在以下情况下运行:
FIN
/ RST
,套接字读取超时,TCP保持活动失败,文件描述符由另一个线程close
d) ; SA_RESTART
; pthread_cancel
领导。您尝试更改另一个线程的文件描述符的标志这一事实表明您的设计需要审核。理想情况下,线程不得共享任何数据,也不得互相攻击彼此的状态,而应使用消息传递来相互通信。
答案 1 :(得分:0)
未阻止线程(由于在阻止模式下读取而未阻止)将表现得好像它始终是非阻塞模式。
如果套接字上没有可用的消息,并且套接字是非阻塞的,则返回值-1和外部 变量errno设置为EAGAIN或EWOULDBLOCK。
阻止线程(在阻止模式下读取时被阻止),然后更改为非阻塞。 正如@Maxim共享未唤醒线程的函数代码所指出的那样,阻塞的线程只会在写入完成后被唤醒(数据可用)。