如何用单线程实现TCP上的全双工通道?
我正在编写的网络库需要通过 TCP 套接字发送和接收消息。消息可以随时发送或接收,即应该作为全双工通道工作。
我能够使用两个线程来实现这样的场景:调用 send() 的主线程和一个主要在 receive() 调用处阻塞的专用线程。
我的问题是:是否可以用单线程实现相同的场景?即通过注册一些回调函数?
附带说明:我需要用 C++、Java 和 Python 实现这个场景。
The network lib I'm writing needs to send and receive messages through a TCP socket. Messages can be sent or received any time, i.e should work as a full duplex channel.
I was able to implement such scenario using two threads: main thread calling send() and a dedicated thread mostly blocked at recv() call.
My question is: is it possible to implement the same scenario with a single thread? I.e. by registering some callback function?
As a side note: I need implement this scenario in C++, Java and Python.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,有可能。您需要使用允许多路复用 I/O 的 API。在 C/C++ 和 Python 下,您可以使用 select() 和非阻塞 I/O,因此您阻塞的唯一网络调用就是 select()。还有 poll() 和 epoll() 以及许多其他类似的 API 可以完成相同的任务,但效率和可移植性程度不同。 Java 还有非阻塞 I/O API。
另一种可能性是使用异步 I/O,您告诉操作系统启动 I/O 事务,并在完成操作时通知您(通过某种机制)。不过,我不熟悉这种网络编程风格,因此我不会尝试提供详细信息。
Yes, it possible. You need to use an API that allows multiplexed I/O. Under C/C++ and Python you can use select() and non-blocking I/O, so that the only networking call you ever block in is select(). There is also poll() and epoll() and a number of other similar APIs that accomplish the same thing, with varying degrees of efficiency and portability. Java has non-blocking I/O APIs also.
Another possibility is to use asynchronous I/O, where you tell the OS to start an I/O transaction and it notifies you (by some mechanism) when it has finished the operation. I'm not familiar with that style of network programming, however, so I won't try to give details.
一般来说,库将通过提供应用程序主循环/事件循环的接口来实现此目的。
例如,大多数使用单线程网络的应用程序都会有一个在
select()
、poll()
或类似的循环中阻塞的主循环。您的库只会返回一个文件描述符,应用程序应将其包含在其select()
/poll()
调用中,以及应用程序在该文件时应调用的回调函数描述符是可读的。In general, a library would do this by providing an interface into the application's main loop / event loop.
For example, most single-threaded network-using applications would have a main loop that blocks in
select()
,poll()
or similar. Your library would just return a file descriptor that the application should include in itsselect()
/poll()
call, and a callback function that the application should call when that file descriptor is readable.