在同一个套接字上发送/recv 的并行调用是否有效?

  1. 我们可以在同一个套接字上从一个线程调用 send,从另一个线程调用 recv 吗?
  2. 我们可以从同一个套接字上的不同线程并行调用多个发送吗?

我知道一个好的设计应该避免这种情况,但是我不清楚这些系统 API 将如何运行。我无法找到一个好的文件也为同样。

方向上的任何指示都会有帮助。

62580 次浏览

我看不出并行接收怎么可能完成任何事情。如果你有一个3字节的消息,一个线程可以得到前2个字节,另一个线程可以得到最后一个字节,但是你没有办法分辨哪个是哪个。除非您的消息只有一个字节长,否则您不可能可靠地使任何东西在接收多个线程的情况下工作。

多个发送 也许吧工作,如果你发送整个消息在一个单一的调用,但我不确定。有可能一个会覆盖另一个。这样做当然不会带来任何性能上的好处。

如果需要发送多个线程,则应实现同步消息队列。有一个线程实际发送从队列中读取消息,另一个线程将整个消息排入队列。同样的事情也适用于接收,但是接收线程必须知道消息的格式,这样才能正确地反序列化它们。

POSIX 将 send/recv 定义为原子操作,因此假设您讨论的是 POSIX send/recv,那么是的,您可以从多个线程同时调用它们,这样就可以工作了。

这并不一定意味着它们将并行执行——在多个发送的情况下,第二个发送可能会被阻塞,直到第一个发送完成。您可能不会注意到这一点,因为一旦将数据放入套接字缓冲区,发送就完成了。

如果您使用的是 SOCK _ STREAM 套接字,尝试并行处理不太可能有用,因为 send/recv 可能只发送或接收消息的一部分,这意味着事情可能会被分解。

阻塞 SOCK _ STREAM 套接字上的 send/recv 只会阻塞直到它们发送或 recv 至少1个字节,因此阻塞和非阻塞之间的区别是没有用的。

套接字描述符属于进程,而不属于特定的线程。因此,可以在不同的线程中向同一个套接字发送/接收,操作系统将处理同步。

但是,如果发送/接收的顺序在语义上很重要,您自己(分别是您的代码)必须确保不同线程中的操作之间有适当的顺序-对于线程来说总是如此。