我正在尝试使用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
答案 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";
}
}
原子不是解决此问题的正确方法,您的代码非常慢。互斥体可能会更快。