用非原子更新原子变量,反之亦然

Updating an atomic variable with a non atomic and vice versa

本文关键字:反之亦然 变量 更新      更新时间:2023-10-16

我正在从一个线程更新一个原子变量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的值可以更改,但将返回旧值。