3

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

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

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

4

2 回答 2

3

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

async_write()最终调用的post()方法io_service,这反过来会锁定并将要写入的位推送到工作队列中,确保位不会被交错写入。这些位最终将被写出,并且保存它们的基础数据结构(char 数组或其他)必须保持有效,直到您收到表示写入已完成的回调。如果您使用与完成处理程序完全相同的回调函数,您将无法知道这两个写入中的哪一个导致该函数被调用,并且如果该函数执行任何非线程安全的操作,则行为可能未定义或不正确。处理这种情况的一种流行方法是拥有一个作为完成处理程序的结构实例(只需重载 call () 运算符):

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

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

于 2009-12-18T22:05:01.577 回答
0

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

于 2009-12-16T16:02:10.633 回答