用非原子更新原子变量,反之亦然
Updating an atomic variable with a non atomic and vice versa
我正在从一个线程更新一个原子变量size_t并从另一个线程读取它。以下是代码:
法典:
// MyClass.hpp
#pragma once
#include <atomic>
class MyClass {
public:
size_t GetVal() {
return m_atomic_val;
}
void SetVal(const std::size_t val) {
m_atomic_val = val;
}
private:
std::atomic<size_t> m_atomic_val{0};
};
// main.cpp
#include "MyClass.hpp"
#include <iostream>
#include <thread>
int main() {
MyClass obj;
obj.SetVal(4);
std::thread my_thread = std::thread([&obj]{
std::cout << "Thread started" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(30));
obj.SetVal(8);
});
std::this_thread::sleep_for(std::chrono::seconds(2));
auto val = obj.GetVal();
std::cout << "The value is: " << val << std::endl;
my_thread.join();
}
问题:
但正如你所看到的,我正在更新
m_atomic_val
,这是一个std::atomic<size_t>
,size_t
是非原子的。这会产生不良影响吗?这是违法的吗?GetVal
的返回类型是size_t
,但其返回是std::atomic<size_t>
。这有错吗?因此,我的主要问题是,是否允许我在示例代码中以这种方式混合原子和非原子变量?
这只是一个简单的例子来说明我的问题。如果有一个编写器线程和一个读取器线程同时运行并且很可能出现争用条件,该怎么办?我应该改用互斥体而不是原子组学吗?
环境:
我的代码在iOS,Android和macOS上运行。
对原子对象的赋值将接受正确类型的任何值。
由于您有std::atomic<size_t>
因此可以在赋值的右侧使用任何(或可以隐式转换为(size_t
的值或变量。
至于GetVal
问题,std::atomic
有一个转换运算符,它将做正确的事情,原子地获取值并将其交给您返回。
关于GetVal
函数的另一个注意事项:它只会是获取原子值,它的return
不会。因此,在获取和实际return
之间,m_atomic_val
的值可以更改,但将返回旧值。
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 为"adjacent"变量赋值时出现问题
- enum是C++中的宏变量还是整数变量
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 用C++中的一个变量定义一个常量
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 你能重载对象变量名本身返回的内容吗
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 尝试通过多个向量访问变量时,向量下标超出范围
- 试图让变量检查数组中的某些内容
- Cpp-Tuple使用带有变量的get
- 将包含C样式数组的对象初始化为成员变量(C++)
- 当vector是tje全局变量时,c++中vector的内存管理
- 用非原子更新原子变量,反之亦然
- 将非按引用变量分配给返回按引用的函数,反之亦然
- 将变量/值从PHP传递到打开的窗口进程,反之亦然