用 atomic bool 同步 10 个线程
synchronizing 10 threads with atomic bool
我正在尝试使用 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
您在使用 atomic
时有 2 个错误。
当compare_exchange_weak 失败时,它将当前值存储在第一个参数中。如果您想继续尝试相同的值,您需要将其设置回原始值:
while ((turn.compare_exchange_weak(f, false)) == false)
{
f = true;
}
第二个问题是exchange
returns当前存储的值所以:
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";
}
}
原子不是解决这个问题的正确方法,您的代码非常慢。互斥量可能会更快。
我正在尝试使用 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
您在使用 atomic
时有 2 个错误。
当compare_exchange_weak 失败时,它将当前值存储在第一个参数中。如果您想继续尝试相同的值,您需要将其设置回原始值:
while ((turn.compare_exchange_weak(f, false)) == false)
{
f = true;
}
第二个问题是exchange
returns当前存储的值所以:
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";
}
}
原子不是解决这个问题的正确方法,您的代码非常慢。互斥量可能会更快。