我们可以从一个线程调用send并在同一个套接字上从另一个调用recv吗?
我们可以从同一个套接字上的不同线程并行调用多个发送吗?
我知道一个好的设计应该避免这种情况,但我不清楚这些系统API将如何表现 . 我也找不到相同的好文档 .
方向上的任何指针都会有所帮助 .
POSIX将send / recv定义为原子操作,所以假设您正在谈论POSIX send / recv然后是,您可以从多个线程同时调用它们,事情就可以了 .
这并不一定意味着它们将并行执行 - 在多次发送的情况下,第二次可能会阻塞直到第一次完成 . 您可能不会注意到这一点,因为一旦将数据放入套接字缓冲区,发送就会完成 .
如果您正在使用SOCK_STREAM套接字,那么尝试并行操作不太可能有用,因为send / recv可能只发送或接收部分消息,这意味着事情可能会被拆分 .
阻止SOCK_STREAM套接字上的send / recv仅阻塞,直到它们发送或recv至少1个字节为止,因此阻塞和非阻塞之间的区别无用 .
套接字描述符属于进程,而不属于特定线程 . 因此,可以在不同线程中向/从相同套接字发送/接收,OS将处理同步 .
但是,如果发送/接收的顺序在语义上很重要,那么您自己(分别是您的代码)必须确保在不同线程中的操作之间进行正确排序 - 就像线程一样 .
我不知道并行接收是否可能完成任何事情 . 如果你有一个3字节的消息,1个线程可以获得前2个字节,另一个线程可以获得最后一个字节,但是你无法分辨哪个是哪个 . 除非您的消息只有一个字节长,否则您无法可靠地使多个线程接收任何工作 .
如果您在一次调用中发送了整个消息,则多个发送可能有效,但是我可能会覆盖另一个消息 . 这样做当然不会有任何性能上的好处 .
如果需要发送多个线程,则应实现同步消息队列 . 有一个线程执行实际发送,从队列中读取消息并让其他线程将整个消息排入队列 . 同样的事情适用于接收,但接收线程必须知道消息的格式,以便它可以正确地反序列化它们 .
3 回答
POSIX将send / recv定义为原子操作,所以假设您正在谈论POSIX send / recv然后是,您可以从多个线程同时调用它们,事情就可以了 .
这并不一定意味着它们将并行执行 - 在多次发送的情况下,第二次可能会阻塞直到第一次完成 . 您可能不会注意到这一点,因为一旦将数据放入套接字缓冲区,发送就会完成 .
如果您正在使用SOCK_STREAM套接字,那么尝试并行操作不太可能有用,因为send / recv可能只发送或接收部分消息,这意味着事情可能会被拆分 .
阻止SOCK_STREAM套接字上的send / recv仅阻塞,直到它们发送或recv至少1个字节为止,因此阻塞和非阻塞之间的区别无用 .
套接字描述符属于进程,而不属于特定线程 . 因此,可以在不同线程中向/从相同套接字发送/接收,OS将处理同步 .
但是,如果发送/接收的顺序在语义上很重要,那么您自己(分别是您的代码)必须确保在不同线程中的操作之间进行正确排序 - 就像线程一样 .
我不知道并行接收是否可能完成任何事情 . 如果你有一个3字节的消息,1个线程可以获得前2个字节,另一个线程可以获得最后一个字节,但是你无法分辨哪个是哪个 . 除非您的消息只有一个字节长,否则您无法可靠地使多个线程接收任何工作 .
如果您在一次调用中发送了整个消息,则多个发送可能有效,但是我可能会覆盖另一个消息 . 这样做当然不会有任何性能上的好处 .
如果需要发送多个线程,则应实现同步消息队列 . 有一个线程执行实际发送,从队列中读取消息并让其他线程将整个消息排入队列 . 同样的事情适用于接收,但接收线程必须知道消息的格式,以便它可以正确地反序列化它们 .