从另一个线程关闭套接字时,阻止recv不会退出?

时间:2010-09-02 06:43:02

标签: c linux sockets

在Linux中,如果我们从一个线程调用阻塞recv并从另一个线程关闭同一个套接字,则recv不会退出。

为什么?

2 个答案:

答案 0 :(得分:11)

“为什么”只是因为设计的原因。

在内核中,recv()调用在与文件描述符对应的fget()上调用struct file,这将阻止它被释放,直到相应的fput()

你只需要改变你的设计(无论如何你的设计都是天生的 - 为了实现这一点,你必须没有锁定来保护用户空间中的文件描述符,这意味着close()可能只发生了< em>在 recv()调用之前 - 文件描述符甚至被重用于其他东西)。


如果你想唤醒另一个阻塞文件描述符的线程,你应该让它在select()上阻塞,而是在主线程可以写入的文件描述符集中包含一个管道。

答案 1 :(得分:7)

检查套接字的所有文件描述符是否已关闭。如果在“远程端”仍然打开(假设这是您尝试关闭的那个),则为“peer has not performed an orderly shutdown”。

如果仍然无效,请拨打远端的shutdown(sock, SHUT_RDWR),无论引用次数如何,都会关闭套接字。