当同一套接字上的发送/接收正在进行时,是否可以从另一个线程关闭该套接字? [英] Can a socket be closed from another thread when a send / recv on the same socket is going on?
本文介绍了当同一套接字上的发送/接收正在进行时,是否可以从另一个线程关闭该套接字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
当同一套接字上的发送/接收正在进行时,是否可以从另一个线程关闭该套接字?
假设一个线程正在阻止recv调用,而另一个线程关闭了同一个套接字,recv调用中的线程会知道这一点并安全退出吗?
我想知道不同操作系统/平台的行为是否会有所不同。如果是,它在Solaris中会有什么表现?
推荐答案
我不知道Solaris网络堆栈的实现,但我会提出我的理论/解释为什么它应该是安全的。
- 线程A进入某个阻塞系统调用,比如
read(2)
,用于这个给定的套接字。套接字接收缓冲区中没有数据,因此线程A被从处理器中移除并放入该套接字的等待队列中。此处未启动任何网络堆栈事件,连接状态(假定为TCP)未更改。 - 线程B在套接字上发出
close(2)
。虽然内核套接字结构应该在线程B访问它时被锁定,但没有其他线程持有该锁(线程A在它进入休眠-等待时释放了锁)。假设套接字发送缓冲区中没有未完成的数据,则发送FIN
包,连接进入FIN WAIT 1
状态(这里我再次假定为TCP,请参阅connection state diagram) - 我猜套接字连接状态更改将为给定套接字上阻塞的所有线程生成唤醒。也就是说,线程A将进入可运行状态,并发现连接正在关闭。如果对方尚未发送自己的
FIN
,则可能重新进入等待,否则系统调用将返回eof
。
在任何情况下,内部内核结构都将受到保护,不会受到不适当的并发访问。这并不意味着从多个线程执行套接字I/O是个好主意。我建议研究非阻塞套接字、状态机和像libevent
这样的框架。
这篇关于当同一套接字上的发送/接收正在进行时,是否可以从另一个线程关闭该套接字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文