2009-12-16 154 views
2

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

  • 如果我开始在同一插座上的两个或两个以上ASYNC_WRITE无需等待第一个完成,会发生什么?处理程序(和async_write)重叠还是asio提供序列化和同步?

    • 以上同样的问题与async_connect和async_read。一般来说,从不同线程调用这些函数是安全的(我不是在谈论使用不同的缓冲区,这是另一个问题......)。

回答

2

我从你的问题中假设你有一个io_service实例,并且你想从多个线程调用它的asyncwrite()。 asyncwrite()最终调用ioservice的post()方法,该方法依次获取一个锁并将这些位写入工作队列,确保这些位不会被交错写入。这些位最终会被写出来,并且持有它们的底层数据结构(char数组或其他)必须保持有效,直到获得表示写入已完成的回调。如果您使用完全相同的回调函数作为完成处理程序,则无法知道哪个写入会导致该函数被调用,并且如果该函数执行的任何操作都不是线程安全的,则行为可能未定义或不正确。处理这种情况的一种常见方式是建立一个结构体的实例,它是完成处理程序(只是重载()运算符):您可以设置结构的属性来表示它对应的写入,然后在完成处理程序被调用。

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

同样的情况适用于asyncreads。您当然可以交叉调用(即在调用完成处理程序之前执行一个asyncread和另一个asyncread,然后执行另一个),但不能保证按照您打算的顺序执行该命令,而无需使用某些外部手段来确保这一点。

0

如果在同一插座上启动两个异步操作,他们可以发生在任何顺序。只要他们使用不同的缓冲区,它是“安全的”,因为它不会崩溃,但这种行为几乎从来都不是你想要的。