线程之间无锁的数据可见性 [英] data visibility between threads without lock

查看:129
本文介绍了线程之间无锁的数据可见性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解C ++ 11中内存排序的基本规则,尤其是发布获取排序.我有两个线程之间共享一个很大的内存,我不需要原子性,但是想确保最终一个线程所做的所有更改在另一个线程中可见,尤其是在具有轻松内存模型的平台上.

I understand the basic rules for memory ordering in C++11, especially release-acquire ordering. I have a big chunk of memory shared between two threads, where I do not need atomicity, but want to ensure that eventually all the changes done by a thread is visible in another, especially on platforms with relaxed memory model.

仅使用原子保护变量来触发内存同步可以吗?例如,

Is it ok to simply use an atomic guard var only to trigger memory synchronization? E.g.,

std::atomic<bool> guardVar;
char *shared_mem=get_shared_mem();

(thread 1)
while(true) {
  happens_many_things();
  do_whatever_I_want_with_shared_mem();
  guardVar.store(0, std::memory_order_release);
}

(in thread 2)
while(true) {
  guardVar.load(std::memory_order_acquire);
  read_shared_mem_no_problem_if_inconsistent();
}

同样,如果线程2在do_whatever_I_want_with_shared_mem()的中间读取半就绪"状态,这不是问题,我只是想确保在定义明确的点之后,得到线程1编写的所有更改.

Again, it is not a problem if thread 2 reads a "half-ready" state in the middle of do_whatever_I_want_with_shared_mem(), I just want to ensure that I get all the changes written by thread 1 after a well defined point.

基于本文,它应该可以工作,但我不起作用可以在网上看到类似的解决方案,并且很难测试它是否确实符合我的预期.

Based on this article it should work, but I do not see solutions like this on the net, and is not easy to test if it really does what I intend.

可以吗?如果是的话,还有没有更优雅的方式?

Is it ok? If it is, is there a more elegant way?

推荐答案

如果线程2在do_whatever_I_want_with_shared_mem()的中间读取半就绪"状态,这不是问题

it is not a problem if thread 2 reads a "half-ready" state in the middle of do_whatever_I_want_with_shared_mem()

这是一个错误,如果其中一个线程正在修改数据,则无法通过多个线程访问共享内存. C ++标准将其称为数据竞赛,并导致未定义的行为.

This is an error, you cannot access shared memory by multiple threads if one of them is modifying the data. The C++ standard calls it a data race and it leads to undefined behavior.

两个线程之间的访问需要同步,但是使用std::atomic的方式不正确.线程1中的store_release之后立即再次访问相同的数据.与load_acquire相同;这两个操作之间没有同步,因此您正在处理数据争用.

Access between the two threads needs to be synchronized, but the way you use the std::atomic is incorrect. The store_release in thread 1 is immediately followed by accessing the same data again. Same for the load_acquire; there is no synchronization between the two operations and hence you are dealing with a data race.

为了确保您的共享内存一次只能被一个线程访问,guardVar在技术上可以这样使用:

To ensure that your shared memory is only accessed by one thread at a time, guardVar can technically be used like this:

std::atomic<bool> guardVar{false};

(thread 1)
while(true) {

    while (guardVar.exchange(true, std::memory_order_acquire));  // LOCK

    happens_many_things();
    do_whatever_I_want_with_shared_mem();

    guardVar.store(false, std::memory_order_release);  // UNLOCK
}

(in thread 2)
while(true) {

    while (guardVar.exchange(true, std::memory_order_acquire)); // LOCK

    read_shared_mem_no_problem_if_inconsistent();

    guardVar.store(false, std::memory_order_release);  // UNLOCK
}

但是由于这是以一种相当低效的方式(请注意旋转)将std::atomic用作互斥体,因此您确实应该使用std::mutex

But since this is using a std::atomic as a mutex in a rather inefficient way (note the spinning), you really should use a std::mutex

更新:

仍然可以不加锁定地使用共享内存,但是您有责任确保在共享内存中访问的每个单个对象都不受数据争用的影响(std::atomic对象符合条件).

It is still possible to use your shared memory without locking, but then it is your responsibility to ensure that each individual object that is accessed in shared memory is data race free (std::atomic objects qualify).

然后,您或多或少地得到了您在问题中描述的行为,其中第二个线程可能会看到半就绪"状态(某些对象已更新,而其他对象则未更新).如果没有同步,第二个线程将无法真正知道第一个线程的更新何时完成,但至少可以安全地同时读取/写入不受数据争用的对象.

Then you more or less get the behavior you describe in your question where a second thread may see a "half-ready" state (some objects updated, others are not). Without synchronization the second thread cannot really know when the updates by the first thread are done, but at least it is safe to read/write to the data race free objects concurrently.

这篇关于线程之间无锁的数据可见性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆