Asio异步和并发

时间:2009-12-16 15:49:36

标签: c++ boost-asio

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

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

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

2 个答案:

答案 0 :(得分:2)

我从你的问题中假设你有一个io_service实例,你想从多个线程上调用asyncwrite()。

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

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

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

答案 1 :(得分:0)

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