我正在用 boost::asio
编写一些代码,使用异步 TCP 连接。我不得不承认我对此有些怀疑。所有这些都与并发有关。这里有一些:
如果我在同一个套接字上启动两个或多个
async_write
而没有等待第一个完成,会发生什么情况?处理程序(和async_write
)是否重叠或asio
提供序列化和同步?关于
async_connect
和async_read
的相同问题。一般来说,从不同的线程调用这些函数是否安全(我不是在谈论使用不同的缓冲区,那是另一个问题......)。
最佳答案
根据您的问题,我假设您有一个 io_service
实例,并且您想从多个线程对其调用 async_write()
。
async_write()
最终调用了io_service
的post()
方法,后者又获取了一个锁并压入要写入的位进入工作队列,确保位不会被交错写入。这些位最终将被写出,并且保存它们的底层数据结构(字符数组或其他)必须保持有效,直到您收到表示写入已完成的回调。如果您使用与完成处理程序完全相同的回调函数,您将无法知道两次写入中的哪一次导致调用该函数,如果该函数执行任何非线程安全的操作,则行为可能未定义或不正确。处理这种情况的一种流行方法是拥有一个作为完成处理程序的结构实例(只需重载调用 () 运算符):您可以设置结构的属性以指示它对应于哪个写入,然后查询这些值当调用完成处理程序时。
但是,如果没有共享锁,您将无法控制哪个线程实际执行其 async_write()
方法。事实上,即使您启动两个线程并让一个线程立即调用 async_write()
并让另一个线程休眠一个小时然后调用 async_write()
,您也是仍然不能确定操作系统没有愚蠢地安排你的线程并首先执行第二个线程的调用。 (这个例子是病态的,但观点是普遍有效的。)
同样的情况也适用于async_read()
。您当然可以交错调用(即执行一次 async_read()
,然后在调用完成处理程序之前执行另一次)但是不能保证在没有一些外部手段来确保这一点的情况下将按照您想要的顺序执行.
关于c++ - Asio 异步和并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1915520/