簡體   English   中英

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 引用,因此將 function 優化為類似以下內容是合理的:

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值傳遞到 function 中,期望對非原子類型的 const 引用。 我沒有看過標准,但我在 cppreference 上沒有看到任何表明允許這種轉換的內容。

我在這里誤解了什么嗎? 這只是std::atomic的一些怪癖,我從文檔中看不出來嗎?

這是因為在傳遞std::atomic<bool>時調用do_something(const bool &stop)時存在隱式轉換

它翻譯成:

do_something(static_cast<bool>(stop.operator bool()));

正如您在這里看到的: https://en.cppreference.com/w/cpp/atomic/atomic/operator_T

您實際上告訴編譯器加載一次值,就在調用時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM