2016-11-11 84 views
2

宣稱std::vectorthread_local是否有優勢? 像什麼時候有人將std :: vector定義爲thread_local?

static unique_ptr<std::vector<ObjectA>> vecVariable; 

的聲明std::vector作爲thread_local不會使其操作,如pop_back()erase()同步。

由於在每一個STL容器,如果有一個線程修改的容器,然後應無併發線程讀取或寫入同一容器中,所以我不能在並行/多線程環境做erase()pop_back()一個vector對象。

即使我聲明向量爲thread_local,我的代碼在其中一個操作中崩潰。我知道我可能需要在鎖定下完成這些操作,但我只是想了解何時有人會將std::vector定義爲thread_local

+0

同時他們將任何變量定義爲thread_local - 當它們每個線程都有自己的實例時。 – davmac

回答

4

thread_local導致一個對象有線程存儲,這意味着每個線程都會有自己獨立的對象實例。它不會以任何方式影響對象的線程安全性,因爲您似乎暗示您認爲它應該。

如果您希望每個線程都擁有自己的變量實例,您將聲明一個vector變量或任何其他變量,thread_local。如果您想要能夠同時訪問單個對象,解決方案不是聲明它,而是使用線程安全數據類型或適當的同步基元(例如通過鎖定和解鎖std::mutex)。

+0

@GillBates每個線程_can_訪問屬於其他線程的副本,如果它可以通過其他方式獲得對它們的引用。名稱引用不同線程中的不同對象並不意味着線程安全。 – davmac

+0

當然他們可以通過地址傳遞或全球參考。我在談論使用名稱和唯一名稱的情況。 –

+0

正如我所說的,當通過它的名字訪問這個向量中的元素時,不需要首先關心線程安全性。 '矢量[0]'。關鍵字本身不會帶來任何同步,但通過正確使用可避免線程之間的數據競爭,如果線程不依賴其他線程來填充或修改此容器。 –

5

thread_local不意味着用於同步。它意味着作爲存儲持續時間說明符(http://en.cppreference.com/w/cpp/language/storage_duration

藉此例如:

#include <iostream> 
#include <vector> 
#include <thread> 

thread_local std::vector<int> v; 

void func() 
{ 
    v.push_back(5); 
    std::cout<< "t: "<< v.size() << std::endl; 
} 

int main() 
{ 
    v.push_back(3); 
    v.push_back(5); 
    std::thread t1(func); 
    std::thread t2(func); 
    std::cout<< "m: "<< v.size() << std::endl; 
    t1.join(); 
    t2.join(); 
} 

輸出:

m: 2 
t: 1 
t: 1 

thread_local確實的是創建爲每個線程不同載體。在這個例子中你可以看到v來自主線程有2個元素,而其他線程中的矢量v每個只有1個元素。

會發生什麼情況是,當一個新的線程被創建時,程序也會爲這個線程創建一個新的向量。當線程結束時,矢量也會被破壞。

相關問題