在同一套接字上并行调用 send/recv 是否有效?
- 我们可以在同一个套接字上从一个线程调用 send 并从另一个线程调用 receive 吗?
- 我们可以从同一套接字上的不同线程并行调用多个发送吗?
我知道好的设计应该避免这种情况,但我不清楚这些系统 API 的行为方式。我也找不到同样的好的文档。
任何指向该方向的指示都会有所帮助。
- Can we call send from one thread and recv from another on the same socket?
- Can we call multiple sends parallely from different threads on the same socket?
I know that a good design should avoid this, but I am not clear how these system APIs will behave. I am unable to find a good documentation also for the same.
Any pointers in the direction will be helpful.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
POSIX 将 send/recv 定义为原子操作,因此假设您正在谈论 POSIX send/recv 那么是的,您可以从多个线程同时调用它们并且事情会起作用。
这并不一定意味着它们将并行执行——在多次发送的情况下,第二个可能会阻塞,直到第一个完成为止。您可能不会注意到这一点,因为一旦将数据放入套接字缓冲区,发送就完成了。
如果您使用 SOCK_STREAM 套接字,尝试并行执行操作不太可能有用,因为 send/recv 可能只发送或接收消息的一部分,这意味着事情可能会被分割。
在 SOCK_STREAM 套接字上阻塞发送/接收只会阻塞,直到它们发送或接收至少 1 个字节,因此阻塞和非阻塞之间的区别没有用处。
POSIX defines send/recv as atomic operations, so assuming you're talking about POSIX send/recv then yes, you can call them simultaneously from multiple threads and things will work.
This doesn't necessarily mean that they'll be executed in parallel -- in the case of multiple sends, the second will likely block until the first completes. You probably won't notice this much, as a send completes once its put its data into the socket buffer.
If you're using SOCK_STREAM sockets, trying to do things a parallel is less likely to be useful as send/recv might send or receive only part of a message, which means things could get split up.
Blocking send/recv on SOCK_STREAM sockets only block until they send or recv at least 1 byte, so the difference between blocking and non-blocking is not useful.
套接字描述符属于进程,而不属于特定线程。因此,可以在不同线程中向同一套接字发送/接收数据,操作系统将处理同步。
但是,如果发送/接收的顺序在语义上很重要,则您自己(分别是您的代码)必须确保不同线程中的操作之间的正确顺序 - 就像线程的情况一样。
The socket descriptor belongs to the process, not to a particular thread. Hence, it is possible to send/receive to/from the same socket in different threads, the OS will handle the synchronization.
However, if the order of sending/receiving is semantically significant, you yourself (respectively your code) have to ensure proper sequencing between the operations in the different threads - as is always the case with threads.
我不明白并行接收如何可能完成任何事情。如果您有一条 3 字节的消息,则 1 个线程可以获取第一个 2 个字节,另一个线程可以获取最后一个字节,但您无法区分哪个是哪个。除非您的消息只有一个字节长,否则您无法可靠地使任何内容与多个线程接收一起工作。
如果您在一次调用中发送了整个消息,则多次发送可能有效,但我不确定。一个可能会覆盖另一个。这样做肯定不会有任何性能优势。
如果多个线程需要发送,则应该实现同步消息队列。让一个线程执行实际发送操作,从队列中读取消息,并让其他线程将整个消息排入队列。同样的事情也适用于接收,但接收线程必须知道消息的格式,以便它可以正确地反序列化它们。
I don't see how receiving in parallel could possibly accomplish anything. If you have a 3 bytes message, 1 thread could get the 1st 2 bytes and another the last byte, but you'd have no way of telling which was which. Unless your messages are only a byte long, there is no way you could reliably make anything work with multiple threads receiving.
Multiple sends might work, if you sent the entire message in a single call, but I'm not sure. It's possible that one could overwrite another. There certainly wouldn't be any performance benefit to doing so.
If multiple threads need to send, you should implement a synchronized message queue. Have one thread that does the actual sending that reads messages from the queue and have the other threads enqueue whole messages. The same thing would work for receiving, but the receive thread would have to know the format of the messages so it could deserialize them properly.