c++ - Asio 异步和并发

标签 c++ boost-asio asio

我正在用 boost::asio 编写一些代码,使用异步 TCP 连接。我不得不承认我对此有些怀疑。所有这些都与并发有关。这里有一些:

  • 如果我在同一个套接字上启动两个或多个 async_write 而没有等待第一个完成,会发生什么情况?处理程序(和 async_write)是否重叠或 asio 提供序列化和同步?

  • 关于 async_connectasync_read 的相同问题。一般来说,从不同的线程调用这些函数是否安全(我不是在谈论使用不同的缓冲区,那是另一个问题......)。

最佳答案

根据您的问题,我假设您有一个 io_service 实例,并且您想从多个线程对其调用 async_write()

async_write() 最终调用了io_servicepost() 方法,后者又获取了一个锁并压入要写入的位进入工作队列,确保位不会被交错写入。这些位最终将被写出,并且保存它们的底层数据结构(字符数组或其他)必须保持有效,直到您收到表示写入已完成的回调。如果您使用与完成处理程序完全相同的回调函数,您将无法知道两次写入中的哪一次导致调用该函数,如果该函数执行任何非线程安全的操作,则行为可能未定义或不正确。处理这种情况的一种流行方法是拥有一个作为完成处理程序的结构实例(只需重载调用 () 运算符):您可以设置结构的属性以指示它对应于哪个写入,然后查询这些值当调用完成处理程序时。

但是,如果没有共享锁,您将无法控制哪个线程实际执行其 async_write() 方法。事实上,即使您启动两个线程并让一个线程立即调用 async_write() 并让另一个线程休眠一个小时然后调用 async_write(),您也是仍然不能确定操作系统没有愚蠢地安排你的线程并首先执行第二个线程的调用。 (这个例子是病态的,但观点是普遍有效的。)

同样的情况也适用于async_read()。您当然可以交错调用(即执行一次 async_read() ,然后在调用完成处理程序之前执行另一次)但是不能保证在没有一些外部手段来确保这一点的情况下将按照您想要的顺序执行.

关于c++ - Asio 异步和并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1915520/

相关文章:

c++ - 如果我不使用变量,我可以在翻译单元中有多个定义吗?

c++ - 内存分配

c++ - boost::asio::strand::dispatch(handle) 还是直接调用句柄?

c++ - 当对象被分配给一个新对象时,对象会调用它们的析构函数吗?

c++ - ofstream 在看门狗超时前将文件刷新到磁盘

c++ - 使用线程超时 boost ASIO 线程池

boost - 如果调用 asio::strand 的析构函数时,该链上仍有一些就绪/未就绪的处理程序怎么办?

audio - 开始音频编程的最佳方式?

c++ - boost::asio不会触发读取处理程序,而wireshark看到数据进入

matlab - 实时音频处理 : audioDeviceReader 'Driver' not working (MATLAB)