首页 > 解决方案 > 用 atomic bool 同步 10 个线程

问题描述

我正在尝试使用 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

标签: c++multithreadingc++11stdatomic

解决方案


您在使用atomic.

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

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

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

turn = turn.exchange(true);

将 turn back 的值设置为 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";
    }
}

原子不是解决这个问题的正确方法,你的代码非常慢。互斥锁可能会更快。


推荐阅读