2017-07-12 58 views
1
std::uint64_t foo() 
{ 
    static std::uint64_t var = 0u; 

    std::lock_guard<std::mutex> lock(mutex); 

    std::uint64_t b; 

    do 
    { 
     b = bar(); 
    } 
    while (b <= var); 

    var = b; 

    return b; 
} 

假設我們有兩個線程。讓第一個線程在調用lock()之前將變量var讀取到寄存器,並在調用lock()之前將第二個線程讀取變量var到寄存器。然後第一個線程更改var但第二個線程看不到更改,因爲它將值保存在寄存器中。這種情況真的很糟糕嗎?靜態局部變量是否可以被錯誤地優化?

我的意思是,通常只有局部變量是這樣優化的:它們被放到寄存器中,然後從那裏讀取,而不是從主存儲器中讀取。據我所知,全局變量不應該按照這種方式進行優化。但是靜態局部變量呢?

+0

「* ...這種情況真的會發生嗎?*」 - 是的。 'std :: mutex'的同步效果是'unlock()'*與*'lock()'同步。但是你正在討論在lock()之前使用這個對象。互斥體提供的唯一保證是,在lock()''''lock''序列中線程** A **對'bar'的修改,對另一個線程來說是可見的,在** B **'lock()是互斥體之後** B **。 – WhiZTiM

+0

您需要在使用之前鎖定資源,否則另一個線程可能會在賦值和鎖之間鎖定它,從而導致競爭條件 – Dynamitos

+0

@WhiZTiM不* C++ 11 *保證線程安全的靜態? –

回答

0

靜態局部變量有一個全局變量的生命週期,它只是一個函數範圍。您必須像使用適當的全局變量(互斥/原子)一樣保護它。

注:如果使用任何在多線程(我的意思是,當線程使用相同變量)的變量,那麼你就必須讓線程安全的。即使它是一個全局變量。即使如果變量存儲在內存中。將變量存儲在內存中並不能保證線程安全。線程安全是一個擔憂,不是因爲某些變量可能在寄存器中。可能有一個CPU,其中不同的核心不會自動同步它們的緩存。所以,對於一個變量,每個核心的緩存中可能有多個值。

相關問題