与原子布尔同步10个线程

时间:2020-01-25 12:48:38

标签: c++ multithreading c++11 stdatomic

我正在尝试使用10个线程,每个线程都需要打印其编号,并且打印需要同步。我正在做作业,我必须使用原子变量来做(没有锁)。

这是我到目前为止尝试过的:

#include <atomic>
#include <thread>
#include <iostream>
#include <vector>

using namespace std;
atomic<bool> turn = true;

void print(int i);

int main()
{
  vector<thread> threads;

  for (int i = 1; i <= 10; i++)
  {
    threads.push_back(thread(print, i));
  }

  for (int i = 0; i < 10; i++)
  {
    threads[i].join();
  }

  return 0;
}


void print(int i)
{
  bool f = true;
  for (int j = 0; j < 100; j++)
  {
    while((turn.compare_exchange_weak(f, false)) == false)
    { }
    cout << i << endl;
    turn = turn.exchange(true);
  }
}

输出示例:

24 

9143 
541 

2 
8

预期输出:

2
4
9
1
4
3
1
5 
4
10
8

1 个答案:

答案 0 :(得分:3)

使用atomic时有2个错误。

当compare_exchange_weak失败时,它将当前值存储在第一个参数中。如果要继续尝试相同的值,则需要将其设置回原始值:

while ((turn.compare_exchange_weak(f, false)) == false)
{
  f = true;
}

第二个问题是exchange返回当前存储的值,因此:

turn = turn.exchange(true);

将turn turn的值设置为false,您只需要:

turn.exchange(true);

甚至只是:

turn = true;

在这种情况下,实际上并不需要同步,因为std::cout将为您完成同步,单个输出操作不会重叠,因此您只需将print函数更改为以下函数即可使用:

void print(int i)
{
    for (int j = 0; j < 100; j++)
    {
        cout << std::to_string(i) + "\n";
    }
}

原子不是解决此问题的正确方法,您的代码非常慢。互斥体可能会更快。

相关问题