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

Jay*_*Jay 4 c sockets linux

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

为什么?

caf*_*caf 12

"为什么"只是它的设计方式.

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

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


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

  • @Jay:一旦调用了`close()`,你就不应该在文件描述符上调用`recv()`.如果你很幸运,你会得到`EBADF`,但如果你运气不好,你可以从另一个线程新开的完全不同的套接字中读取. (6认同)

Mat*_*ner 7

检查套接字的所有文件描述符是否已关闭.如果在"远程端"仍然打开(假设这是您尝试关闭的那个),则" 对等体未执行有序关闭 ".

如果这仍然不起作用,请shutdown(sock, SHUT_RDWR)在远程端调用,无论引用计数如何,都将关闭套接字.