C套接字阻塞调用 [英] C socket blocking call
问题描述
我想知道套接字在阻止和非阻止操作上的行为.当套接字阻塞模式更改时,套接字上的线程阻塞会发生什么情况?这是场景; 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发生了什么?是因为套接字不再阻塞而发出信号/唤醒了吗?
行为实际上是未指定的:不需要fcntl
即可取消阻塞任何线程.
Linux只是在中设置该标志文件描述 struct file
并返回而不会取消阻止任何被阻止的线程.
仅在以下情况下,可以调度在recv
中被阻塞的线程 :
- 要读取的数据可用;
- 或检测到文件描述符上的错误情况(
FIN
/RST
,套接字读取超时,TCP保持活动失败,文件描述符由另一个线程close
d); - 或已接收信号,并且信号处置不包括
SA_RESTART
; - 或者它是
pthread_cancel
led.
您试图更改另一个线程的文件描述符标志的事实表明您的设计需要进行审查.理想情况下,线程不得共享任何数据且不得戳破彼此的状态,而应使用消息传递来相互通信.
I wonder about the behaviour of socket on blocking and nonblocking actions. What happens to threads blocking on socket when the socket blocking mode changes ? Here is the scenario; thread1(T1) creates a UDP socket and
fd = socket(AF_INET , SOCK_DGRAM, 0);
T1 waiting(sleeping) for receive
recv(fd, buf , sizeof(buf) , 0);
and thread2(T2) changes socket mode to non-blocking before socket receive any data
fcntl(fd, F_SETFL, O_NONBLOCK);
what happens to T1 ? Is it signalled/waked because the socket is no more blocking ?
The behavior is literally unspecified: fcntl
is not required to unblock any threads.
A thread already blocked in recv
can be scheduled to run only if:
- data to read becomes available;
- or an error condition on the file descriptor is detected (
FIN
/RST
, socket read timeout, TCP keep-alive failure, the file descriptor isclose
d by another thread); - or a signal is received and the signal disposition does not include
SA_RESTART
; - or it is
pthread_cancel
led.
The fact that you are trying to change flags of a file descriptor of another thread suggests that your design requires a review. Ideally, threads must not share any data and not poke at each other's state, rather they should use message passing to communicate with each other.
这篇关于C套接字阻塞调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!