簡體   English   中英

布爾標志應該總是原子的嗎?

[英]Should a boolean flag always be atomic?

假設有一個由主線程控制的布爾標志( keep_running )。 另一個線程無限循環,直到該標志變為false。

int main() {
    bool keep_running(true);
    std::thread run( [](bool &keep_running)
    {
        while(keep_running)
        {
            // do work
        }
    }, std::ref(keep_running) );

    // do other work
    keep_running = false;
    run.join();
    return 0;
}

該標志應該是原子的嗎?

std::atomic<bool> keep_running

我想,非原子版本可能發生的最糟糕的情況是,當

while(keep_running)

被執行。 在這種情況下,循環將繼續運行一次(並非絕對需要)迭代。 但就我而言,這是可以接受的。

上面的代碼可能有錯誤的情況嗎?

編輯:

出於性能原因(並且沒有錯誤),我對此最感興趣。 因此,對循環中的標志使用std :: atomic是否會對性能產生負面影響?

這只是C ++ 11標准,它禁止並發訪問非原子變量(將它們標記為Undefined Behavior )。

因此,您需要將此變量聲明為atomic。

請注意,對讀取值使用keep_running.load(std::memory_order_relaxed) ,對寫入值使用keep_running.store(true, std::memory_order_relaxed)將消除任何額外的性能開銷,因此生成的代碼將與沒有原子的代碼一樣快。


我想,非原子版本可能發生的最糟糕的情況是該標志在當時被正確設置。

可能發生的情況是,在您的線程中,變量將被存儲到寄存器中,並且永遠不會被重新加載(因此,線程將永遠不會停止)。 如果沒有atomic或其他特殊類型和修飾符,則允許編譯器執行此操作,而實際上是這樣做的。

暫無
暫無

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

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