我正在使用异步tcp连接使用boost asio编写一些代码。我不得不承认我对此有些怀疑。所有这些都涉及到并发性。这里有一些:

  • 如果我在同一套接字上启动两个或多个async_write而不等待第一个套接字的完成会发生什么?处理程序(和async_write)会重叠还是asio提供序列化和同步?
  • 与async_connect和async_read相同的问题。通常,从不同的线程调用这些函数是安全的(我不是在谈论使用不同的缓冲区,这是另一个问题...)。
  • 最佳答案

    我从您的问题中假设您只有一个io_service实例,并且您想从多个线程对其调用asyncwrite()。

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

    但是,如果没有共享锁,则无法控制哪个线程实际执行其asyncwrite方法。实际上,即使您启动了两个线程并让一个线程立即调用asyncwrite并让另一个线程睡眠一个小时然后再调用asyncwrite,您仍然不能保证操作系统不会愚蠢地调度线程并执行第二个线程的先打电话。 (该示例是病理性的,但这一点是普遍有效的。)

    同样的情况适用于异步读取。您当然可以交错调用(即先执行一个asyncread,然后在完成处理程序被调用之前再执行另一个调用),但是并不能保证可以按照您想要的顺序执行,而无需任何外部手段来确保这一点。

    08-25 09:06