在多线程环境中使用atomic保护两个变量
protect two variables with atomic in a multi-threading environement
//线程1
std::uint64_t getAndResetProcessingTimeInMicro()
{
auto value = m_cumulatedProcessingTimeCount.load(boost::memory_order_acquire);
if (value == 0)
return 0;
auto processingTime = m_cumulatedProcessingTime.load(boost::memory_order_relaxed);
resetProcessingTimeInMicro();
return processingTime / value;
}
//线程2
void addProcessingTimeInMicro(std::uint64_t processedTime)
{
m_cumulatedProcessingTime.fetch_add(processedTime, boost::memory_order_relaxed);
//ctxt switch here //-----HERE------
m_cumulatedProcessingTimeCount.fetch_add(1, boost::memory_order_release);
}
线程1计算处理时间的平均值,线程2累加处理时间。
我想确保上下文开关在不引入锁的情况下无法在HERE位置获取数据,我可以通过使用原子对象来实现这个结果吗?
如果要同时执行两个不同的原子操作,则在写入和读取它们时都需要一个互斥体。互斥不会阻止上下文切换,但使用这种方式可以保证您不会访问半更新的状态。
或者,如果您真的不想使用互斥,可以使用单个uint64_t的64位中的一些来存储计数(比如较低的8)。然后你会
m_cumulatedProcessingTime.fetch_add((processedTime << 8) + 1, boost::memory_order_release);
然后检索
auto value = m_cumulatedProcessingTimeCount.load(boost::memory_order_acquire);
auto time = value >> 8;
auto count = value & 0xff;
你可以,但你可能不想。
您需要对包含这两个变量的结构使用原子shared_ptr。读取的过程只是原子地复制shared_ptr
,并查看它指向的结构。写入的过程是:
-
读取原子
shared_ptr
。 -
根据结构中的新值,分配(使用
std::make_shared
)一个新结构,该结构包含两个变量的新值。 -
尝试原子比较/交换,将原子shared_ptr设置为指向新结构。
-
如果比较/交换成功,则完成。
-
释放您创建的新结构,然后返回步骤1。(你可以保证其他作家取得了进步。)
不过你真的不想这么做。只要用一把锁。
生成这样的并集:
union CData {
struct {
__int32 a;
__int16 c;
__int16 d:2,
e:14;
// you get the idea...
}
__int64 n64;
}
使用结构成员使用所有变量,使用n64执行原子操作。
相关文章:
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 我可以创建一个包含两个变量的 for 循环,但时间复杂度仍然为 O(n) 吗?
- 如何更好地检查两个 char 变量是否在一组值中?
- 如何将两个字符串加在一起,就好像它们是变量一样?
- 命令行参数,cant 或两个变量
- 在 for 循环中更新两个变量时遇到问题C++
- 为什么具有静态存储持续时间的同一内联变量在包含在 VS2017 编译的两个翻译单元中时会构造和销毁两次
- C++ 编译时在两个变量之间交替
- C++ 如何在包含两个变量的结构中存储与变量不同数量的值?
- 如何比较两个tm(来自ctime)变量
- 两个不同的进程,在同一地址上有 2 个 std::atomic 变量?
- 如何在 c++ 中将两个不同类型的变量分配给一个变量
- 为什么我不能使用最小和最大这两个词作为变量名称?
- 为什么一个接一个声明的两个变量在内存中不相邻?
- 在链接到两个 exe 的 dll 中共享全局变量
- C++ 两个线程,共享几个整数变量
- 为什么动态分配的两个变量的内存位置不是连续的?
- 计算两个uint8_t变量之间差值的最快方法是什么?
- 如何使用C++中不是文字的变量在数字中显示单引号和两个引号?假设 6'2" 英尺
- 是否可以在C++中使用宏交换两个变量的出现?