asio :: io_service :: post会不会发生关系?

时间:2015-08-18 06:29:10

标签: c++ concurrency boost-asio

boost::shared_ptr<A> a = boost::shared_ptr<A>(new A);
a->i = 2;
strand.post([a](){assert(a->i == 2)});

io_service.post([a](){assert(a->i == 2)});

当我在thread1中将一个处理程序发布到strand或io_service时,执行处理程序的thread2是否会在发布之前看到数据更改?

Java有类似的事情Executor,它发生在以前的关系:

  

在向Runnable提交Runnable之前的一个线程中的操作   执行程序在执行开始之前发生。同样适用于Callables   提交给ExecutorService。

asio怎么样?

请注意,此问题不会询问已发布到io_service或strand的处理程序的执行顺序。 Asio doc说如果使用strand,post(a)发生在post(b)之前。但是这个问题问:在(a)发布之前(编码顺序)之前的动作是否发生在(a)之后(处理程序执行)?这是关于内存模型。让我澄清一下:

// in thread1
global variable a = 111;
start a new thread2 which will access global variable a

我们知道在thread2启动之前启动thread2之前thread1中的操作。这意味着:1,最终执行顺序与代码顺序相同(编译器或CPU不会更改顺序)。 2,global variable a值设置操作将刷新到主内存(或同步到thread2的CPU缓存),然后thread2将更新为最新值global variable a(当然,直到它开始)。

asio的帖子与这个例子类似,所以我问这个问题。我认为asio的帖子应该在关系之前发生,否则它将毫无用处。但我不确定,我想知道asio是如何做到的。

要发生之前,有3种方式:1,线程开始,加入。 2,锁定和解锁互斥锁。 3,记忆障碍。

1 个答案:

答案 0 :(得分:0)

以下所有内容都与内存排序有关:io_service::post()io_service::dispatch()strand::post()strand::dispatch()。这主要是io_servicestrand的结果,它提供了可以同时使用单个对象的有力保证。在这种情况下,不需要潜在的阻塞同步,例如当dispatch()发布到dispatch()的处理程序可以在<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>函数的上下文中执行时,则会发出full memory fence

documentation注意到使用内存屏障进行处理程序分配:

  

[...]如果需要从不同的线程调用分配函数,实现将插入适当的内存屏障以确保正确的内存可见性。