【问题标题】:how to use boost atomic to remove race condition?如何使用 boost atomic 来消除竞争条件?
【发布时间】:2023-03-25 12:40:01
【问题描述】:

我正在尝试使用 boost::atomic 在 linux 上进行多线程同步。

但是,结果并不一致。

任何帮助将不胜感激。

谢谢

#include <boost/bind.hpp>
#include <boost/threadpool.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread.hpp>
#include <boost/atomic.hpp>

boost::atomic<int> g(0) ;

void f()
{

    g.fetch_add(1, boost::memory_order_relaxed);

    return ;
 }
 const int threadnum = 10;
 int main()
 {
    boost::threadpool::fifo_pool tp(threadnum);
    for (int i = 0 ; i < threadnum ; ++i)
            tp.schedule(boost::bind(f));
    tp.wait();
    std::cout << g << std::endl ;
    return 0 ;
  }

【问题讨论】:

  • 我们不了解您的硬件,但memory_order_relaxed 并不是最便携的选择。它肯定会在某些类型的 CPU 上给出不一致的结果。

标签: c++ linux atomic boost-thread race-condition


【解决方案1】:

我不熟悉 boost 线程库或 boost::threadpool,但在我看来,当您访问 g 的值时,线程不一定完成,因此您将获得介于零和之间的一些值10.

这是您的程序,已修改为使用标准库,并插入了连接,以便提取添加发生在 g 的输出之前。

std::atomic<int> g(0);

void f() {
    g.fetch_add(1, std::memory_order_relaxed);
}

int main() {
    const int threadnum = 10;
    std::vector<std::thread> v;

    for (int i = 0 ; i < threadnum ; ++i)
        v.push_back(std::thread(f));

    for (auto &th : v)
        th.join();

    std::cout << g << '\n';
}

编辑:

如果您的程序即使与添加的tp.wait() 仍然不一致,那就令人费解了。添加应该在线程结束之前发生,我认为线程结束将与tp.wait()同步,这发生在读取之前。所以所有的加法都应该在打印 g 之前发生,即使你使用 memory_order_relaxed,所以打印的值应该是 10。

【讨论】:

  • 此时您也可以假设库中存在缺陷。它不是官方/公认的 boost 库。
  • 您可以尝试在 g 上旋转,看看它是否会达到 10。
【解决方案2】:

以下是一些可能有帮助的示例:

基本上,您是在尝试用“锁”来“保护”“关键区域”。

您可以设置或取消设置信号量。

或者你可以“交换”一个提升“原子”变量。例如(来自上面的链接):

class spinlock {
private:
  typedef enum {Locked, Unlocked} LockState;
  boost::atomic<LockState> state_;

public:
  spinlock() : state_(Unlocked) {}

  lock()
  {
    while (state_.exchange(Locked, boost::memory_order_acquire) == Locked) {
      /* busy-wait */
    }
  }
  unlock()
  {
    state_.store(Unlocked, boost::memory_order_release);
  }
};

【讨论】:

    猜你喜欢
    • 2015-03-19
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多