std::atomic 作为非原子类型的 const 引用传递
std::atomic passed as a const reference to a non-atomic type
假设我有这个应用程序:
#include <atomic>
#include <thread>
#include <iostream>
#include <chrono>
void do_something(const std::atomic<bool>& stop) {
while (!stop) {
std::cout << "Doing stuff..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main() {
std::atomic<bool> stop { false };
std::thread wait([&stop] {
std::this_thread::sleep_for(std::chrono::seconds(10));
stop = true;
});
do_something(stop);
wait.join();
}
这按预期工作。主线程循环直到 wait
线程设置 stop
。据我所知,这个应用程序没有真正的问题,因为它使用 std::atomic<bool>
来实现线程之间的同步。
但是,我可以通过将 do_something
的签名更改为这样来破坏应用程序:
void do_something(const bool& stop);
这仍然可以在没有任何警告的情况下编译,但是 do_something
中的循环永远不会退出。从概念上讲,我理解为什么会这样。 do_something
正在接受对非原子值的 const 引用,因此将函数优化为类似以下内容是合理的:
void do_something(const bool& stop) {
if (!stop) {
while(true) {
std::cout << "Doing stuff..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
}
令我困惑的是为什么修改后的应用程序完全可以编译。我不希望能够将 std::atomic
值传递给期望对非原子类型的 const 引用的函数。我没有看过标准,但我在 cppreference 上没有看到任何表明允许这种转换的内容。
我是不是误会了什么?这只是 std::atomic
的一些怪癖,我从文档中看不出吗?
这是因为你调用的时候有隐式转换
do_something(const bool &stop)
通过 std::atomic<bool>
翻译成:
do_something(static_cast<bool>(stop.operator bool()));
如您所见:https://en.cppreference.com/w/cpp/atomic/atomic/operator_T
您实际上告诉编译器加载一次值,就在调用时。
假设我有这个应用程序:
#include <atomic>
#include <thread>
#include <iostream>
#include <chrono>
void do_something(const std::atomic<bool>& stop) {
while (!stop) {
std::cout << "Doing stuff..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main() {
std::atomic<bool> stop { false };
std::thread wait([&stop] {
std::this_thread::sleep_for(std::chrono::seconds(10));
stop = true;
});
do_something(stop);
wait.join();
}
这按预期工作。主线程循环直到 wait
线程设置 stop
。据我所知,这个应用程序没有真正的问题,因为它使用 std::atomic<bool>
来实现线程之间的同步。
但是,我可以通过将 do_something
的签名更改为这样来破坏应用程序:
void do_something(const bool& stop);
这仍然可以在没有任何警告的情况下编译,但是 do_something
中的循环永远不会退出。从概念上讲,我理解为什么会这样。 do_something
正在接受对非原子值的 const 引用,因此将函数优化为类似以下内容是合理的:
void do_something(const bool& stop) {
if (!stop) {
while(true) {
std::cout << "Doing stuff..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
}
令我困惑的是为什么修改后的应用程序完全可以编译。我不希望能够将 std::atomic
值传递给期望对非原子类型的 const 引用的函数。我没有看过标准,但我在 cppreference 上没有看到任何表明允许这种转换的内容。
我是不是误会了什么?这只是 std::atomic
的一些怪癖,我从文档中看不出吗?
这是因为你调用的时候有隐式转换
do_something(const bool &stop)
通过 std::atomic<bool>
翻译成:
do_something(static_cast<bool>(stop.operator bool()));
如您所见:https://en.cppreference.com/w/cpp/atomic/atomic/operator_T
您实际上告诉编译器加载一次值,就在调用时。