Zha*_*ang 4 c++ multithreading c++20
我的目的——只有一个线程可以同时处理数据。我使用过 std::mutex、std::unique_lock,try_lock效果很好。
但有人争论,为什么不直接使用原子变量呢?像这样的事情,
#include <atomic>
#include <thread>
std::atomic_bool isRunning = false;
void process() {
if (isRunning)
{
return;
}
isRunning = true;
cout << "processing ..." << endl;
std::this_thread::sleep_for(std::chrono::seconds(5));
cout << "finished" << endl;
isRunning = false;
}
int main(int argc, wchar_t* argv[])
{
std::thread th1(process);
std::thread th2(process);
std::thread th3(process);
std::thread th4(process);
std::thread th5(process);
th1.join();
th2.join();
th3.join();
th4.join();
th5.join();
}
Run Code Online (Sandbox Code Playgroud)
根据我的经验,atomic 对于写入来说是安全的,但对于读取来说并不安全。例如,if (isRunning)可能有 2 个线程false同时获得相同的值,并且都运行到处理代码中。
但我测试了好几次,都没有这种情况,都只显示一条信息
加工 ...
我没有找到任何相关文档,您对此有何看法?
发布的代码是线程安全的,因为它不会调用未定义的行为,但不是线程安全的,因为它不会为您提供您试图保证的行为。
特别是,此代码中存在竞争条件:
if (isRunning)
{
return;
}
// XXX
isRunning = true;
Run Code Online (Sandbox Code Playgroud)
想象一下这样的场景:线程 A 执行,并到达上面显示 XXX 注释的行...然后操作系统的调度程序抢占线程 A 并允许线程 B 执行,线程 B 设置为并isRunning开始true执行其通常的处理。然后线程 A 回到 CPU,(再次)设置isRunning为true,并开始执行其处理。
此时,线程 A 和线程 B 同时处理数据,这是您试图避免的情况。
结果是:为此目的,互斥锁是完成这项工作的正确工具;原子变量有其用途,但它不会让您(有效地)阻止一个线程的进度,直到另一个线程完成执行关键部分,而这正是您在此程序中想要的行为。
| 归档时间: |
|
| 查看次数: |
517 次 |
| 最近记录: |