原子读然后写 std::atomic
atomic read then write with std::atomic
假设以下代码
#include <iostream>
#include <atomic>
#include <chrono>
#include <thread>
std::atomic<uint> val;
void F()
{
while(true)
{
++val;
}
}
void G()
{
while(true)
{
++val;
}
}
void H()
{
while(true)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout <<"val="<< val << std::endl;
val = 0;
}
}
int main()
{
std::thread ft(F);
std::thread gt(G);
std::thread ht(H);
ft.join();
gt.join();
ht.join();
return 0;
}
基本上是两个线程递增 val
的值,第三个线程每秒报告此值然后重置它。问题是,当第三个线程读取这个值然后将其设置为零时,可能会丢失增量(我们没有将它们包含在报告中)。所以我们需要一个原子的先读后写机制。有没有一种我不知道的干净方法来做到这一点?
PS: 我不想锁定任何东西
std::atomic::exchange
方法似乎是您所追求的(强调我的):
Atomically replaces the underlying value with desired. The operation is read-modify-write operation.
使用如下:
auto localValue = val.exchange(0);
std::cout << "Value = " << localValue << std::endl;
正如其他人提到的那样 std::atomic::exchange
可以。
在两行执行之间提及为什么您当前的代码会按照您所说的执行:
std::cout <<"val="<< val << std::endl;
val = 0;
其他两个线程有时间增加 ht
线程即将重置的值。
std::atomic::exchange
会在一次 "atomic" 操作中完成这些行。
假设以下代码
#include <iostream>
#include <atomic>
#include <chrono>
#include <thread>
std::atomic<uint> val;
void F()
{
while(true)
{
++val;
}
}
void G()
{
while(true)
{
++val;
}
}
void H()
{
while(true)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout <<"val="<< val << std::endl;
val = 0;
}
}
int main()
{
std::thread ft(F);
std::thread gt(G);
std::thread ht(H);
ft.join();
gt.join();
ht.join();
return 0;
}
基本上是两个线程递增 val
的值,第三个线程每秒报告此值然后重置它。问题是,当第三个线程读取这个值然后将其设置为零时,可能会丢失增量(我们没有将它们包含在报告中)。所以我们需要一个原子的先读后写机制。有没有一种我不知道的干净方法来做到这一点?
PS: 我不想锁定任何东西
std::atomic::exchange
方法似乎是您所追求的(强调我的):
Atomically replaces the underlying value with desired. The operation is read-modify-write operation.
使用如下:
auto localValue = val.exchange(0);
std::cout << "Value = " << localValue << std::endl;
正如其他人提到的那样 std::atomic::exchange
可以。
在两行执行之间提及为什么您当前的代码会按照您所说的执行:
std::cout <<"val="<< val << std::endl; val = 0;
其他两个线程有时间增加 ht
线程即将重置的值。
std::atomic::exchange
会在一次 "atomic" 操作中完成这些行。