需要对同步与异步 asio 操作进行一些说明
据我所知,同步和异步操作之间的主要区别(即write()
or read()
vs async_write()
> 和 async_read()
) 前者直到操作完成 - 或错误才返回,后者立即返回.
由于异步操作由 io_service.run()
控制,该操作在受控操作完成之前不会完成.在我看来,在使用 POP3 等协议的 TCP/IP 连接中涉及的顺序操作中,操作是一个序列,例如:
C: 斯:好的.C: 用户...斯:好的.C: 密码斯:好的.C:命令S:回答C:命令S:回答...丙:再见S:<关闭>
同步/异步运算符之间的区别没有多大意义.
当然,在这两种操作中,总是存在程序流程在某些情况下无限期停止的风险――有定时器的使用――,但我想知道更多关于这个问题的权威意见.
我必须承认这个问题相当不明确,但我想听听一些关于何时使用其中一个的建议.我在使用 MS Visual Studio 调试有关我现在工作的 POP3 客户端中的异步 SSL 操作时遇到问题,有时认为在此使用异步可能是个坏主意.
解决方案.
组合(或链接).更高级别的操作可以由多个完成处理程序组成.考虑传输 JPEG 图像,协议可能规定前 40 个字节包括描述图像大小、形状的标头,也许还有一些其他信息.发送此标头的第一个完成处理程序可以启动第二个操作以发送图像数据.更高级别的操作 sendImage()
不需要知道或关心用于实现数据传输的方法链.
超时和取消能力.有一些特定于平台的方法可以使长时间运行的操作超时(例如:SO_RCVTIMEO
和 SO_SNDTIMEO
).使用异步操作可以使用 deadline_timer
在所有支持的平台上取消长时间运行的操作.
当然,在这两个操作中都有始终存在程序流的风险被某些人无限期地停止情况 - 在那里使用计时器-,但我想知道一些更多授权意见在此很重要.
我个人使用 Asio 的经验源于可扩展性方面.为超级计算机编写软件在处理内存、线程、套接字等.使用每个连接的线程进行约 200 万个并发操作是一种在到达时就失效的设计.
As far as I know, the main difference between synchronous and asynchronous operations (i.e. write()
or read()
vs async_write()
and async_read()
) The former ones don't return until the operation finish -or error, and the later ones, returns immediately.
Due the fact that the asynchronous operations are controlled by an io_service.run()
that does not finish until the controlled operations has finalized. It seems to me that in sequential operations as those involved in TCP/IP connections with protocols such as POP3, in which the operation is a sequence such as:
C: <connect>
S: Ok.
C: User...
S: Ok.
C: Password
S: Ok.
C: Command
S: answer
C: Command
S: answer
...
C: bye
S: <close>
The difference between synchronous/asynchronous operators does not make much sense.
Of course, in both operations there is always the risk that the program flow stops indefinitely by some circumstance -there the use of timers-, but I would like know some more authorized opinions in this matter.
I must admit that the question is rather ill-defined, but I would like to hear some advice about when to use one or the other. I've run into problems when debugging with MS Visual Studio regarding asynchronous SSL operations in a POP3 client on which I'm now working, and sometimes think that perhaps it is a bad idea use asynchronous in this.
解决方案The Boost.Asio documentation really does a fantastic job explaining the two concepts. As Ralf mentioned, Chris also has a great blog describing asynchronous concepts. The parking meter example explaining how timeouts work is particularly interesting, as is the bind illustrated example.
First, consider a synchronous connect operation:
The control flow is fairly straightforward here, your program invokes some API (1) to connect a socket. The API uses an I/O service (2) to perform the operation in the operating system (3). Once this operation is complete (4 and 5), control returns to your program immediately afterwards (6) with some indication of success or failure.
The analogous asynchronous operation has a completely different control flow:
Here, your application initiates the operation (1) using the same I/O service (2), but the control flow is inverted. Completion of the operation causes the I/O service to notify your program through a completion handler. The time between step 3 and when the operation has completed was contained entirely within the connect operation for the synchronous case.
You can see the synchronous case is naturally easier for most programmers to grasp because it represents the traditional control flow paradigms. The inverted control flow used by asynchronous operations is difficult to understand, it often forces your program to split up operations into start
and handle
methods where the logic is shifted around. However, once you have a basic understanding of this control flow you'll realize how powerful the concept really is. Some of the advantages of asynchronous programming are:
Decouples threading from concurrency. Take a long running operation, for the synchronous case you would often create a separate thread to handle the operation to prevent an application's GUI from becoming unresponsive. This concept works fine at a small scale, but quickly falls apart at a handful of threads.
Increased Performance. The thread-per-connection design simply does not scale. See the C10K problem.
Composition (or Chaining). Higher level operations can be composed of multiple completion handlers. Consider transferring a JPEG image, the protocol might dictate the first 40 bytes include a header describing the image size, shape, maybe some other information. The first completion handler to send this header can initiate the second operation to send the image data. The higher level operation
sendImage()
does not need to know, or care, about the method chaining used to implement the data transfer.Timeouts and cancel-ability. There are platform specific ways to timeout a long running operation (ex:
SO_RCVTIMEO
andSO_SNDTIMEO
). Using asynchronous operations enables the usage ofdeadline_timer
canceling long running operations on all supported platforms.
Of course, in both operations there is allways the risk that the program flow stops indefinitely by some circunstance -there the use of timers-, but I would like know some more authorized opinions in this matter.
My personal experience using Asio stems from the scalability aspect. Writing software for supercomputers requires a fair amount of care when dealing with limited resources such as memory, threads, sockets, etc. Using a thread-per-connection for ~2 million simultaneous operations is a design that is dead on arrival.
相关文章