簡體   English   中英

初始化 std::atomic_bool ?

[英]Initializing std::atomic_bool?

我想使用std::atomic_bool因為我想要一個應該被不同線程訪問的布爾值。

它是一個static成員變量。 問題是我想用false作為第一個狀態來初始化它。 通常我會這樣做: std::atomic_bool World::mStopEvent = false;

但問題似乎在於它沒有將false作為構造函數。 那么我應該如何初始化這樣一個變量呢? 我正在使用 VS 2012。

這是Visual Studio 2012(稱為 VC11)中的一個已知問題,您應該對現有的 Connect 項目進行投票,以便 Microsoft 知道它會影響更多人,因為他們推遲了修復。

你好,

感謝您報告此錯誤。 我是 Microsoft 的 STL 維護者,我想讓您知道,雖然這個錯誤在我們的數據庫中仍然存在,但它不會在 VC11 RTM (VS 2012 RTM) 中修復。 所有錯誤對我們都很重要,但有些錯誤比其他錯誤更嚴重,並上升到我們優先隊列的頂部。

我在所有 STL 的活動 Connect 錯誤中復制並粘貼此響應,但以下簡潔的評論特別適用於您的錯誤:

  • 是的,我們在atomic_boolatomic_int等上缺少這些構造函數( atomic<bool>atomic<int>等有它們)。 29.5 [atomics.types.generic]/7 說“應該有與 atomic 的整數特化相對應的命名類型,如表 145 中指定的,以及與指定的atomic<bool>相對應的命名類型atomic_bool 。每個命名類型是一個typedef到相應的專業化或相應專業化的基類。如果是基類,則應支持與相應專業化相同的成員函數。” 這讓我真的很想使用 typedef(1 種類型總是比 2 種類型簡單),但我需要看看這是否會引入任何其他問題。

我不能保證我們什么時候能夠解決這個錯誤,但我們希望盡快解決(如果發生這種情況,我會發送另一個回復)——我們的第一個機會將是“帶外” Herb Sutter 在 GoingNative 2012 會議上宣布的 VC11 和 VC12 之間的版本。

注意:Connect 不會通知我有關評論的信息。 如果您有任何進一步的問題,請給我發電子郵件。

Stephan T. Lavavej 高級開發人員 - Visual C++ 庫 stl@microsoft.com

基本上,您現在需要使用std::atomic<T>

嘗試這個:

atomic_bool my_bool = ATOMIC_VAR_INIT(false);

http://en.cppreference.com/w/cpp/atomic/ATOMIC_VAR_INIT

問題:

您不能使用copy-initialization ,因為std::atomic_bool不可復制構造:

std::atomic_bool World::mStopEvent = false; // ERROR!

其實上面的等價於:

std::atomic_bool World::mStopEvent = std::atomic_bool(false); // ERROR!

但是,您可以使用直接初始化

std::atomic_bool World::mStopEvent(false);

根據您的意願,您可以選擇使用大括號而不是圓括號:

std::atomic_bool World::mStopEvent{false};

漏洞:

盡管無論您選擇哪種編譯器,復制初始化都是非法的,但似乎 VC11 附帶的標准庫的實現有一個錯誤,它也不允許您執行直接初始化。

那么我應該如何初始化這樣一個變量呢?

解決方法:

作為一種可能的解決方法,您可以提供一對靜態 getter/setter 包裝器,分別設置和返回原子布爾標志的值,但在確保它已被初始化至少一次且不超過一次之前提供給以線程安全的方式所需的初始值(您可以將其視為某種延遲初始化):

#include <atomic>
#include <mutex>

struct World
{
    static bool is_stop_event_set()
    {
        std::call_once(mStopEventInitFlag, [] () { mStopEvent = false; });
        return mStopEvent;
    }

    static void set_stop_event(bool value)
    {
        std::call_once(mStopEventInitFlag, [value] () { mStopEvent = value; });
        mStopEvent = value;
    }

    static std::atomic_bool mStopEvent;
    static std::once_flag mStopEventInitFlag;
};

std::atomic_bool World::mStopEvent;
std::once_flag World::mStopEventInitFlag;

現在不是直接訪問mStopEvent ,而是通過is_stop_event_set()函數讀取它的值:

#include <iostream>

int main()
{
    std::cout << World::is_stop_event_set(); // Will return false
}

怎么樣:

std::atomic_bool World::mStopEvent(false);

暫無
暫無

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

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