2015-10-16 108 views
0
#include<iostream> 
#include<vector> 
#include<thread> 
#include<string> 

using namespace std; 

vector<string> s; 

void add() 
{ 
    while(true) 
    { 
     getchar(); 
     s.push_back("added"); 
    } 
} 

void show() 
{ 
    while(true) 
    { 
     //cout<<""; 
     while(!s.empty()) 
     { 
      cout<<(*s.begin())<<endl; 
      s.erase(s.begin()); 
     } 
    } 
} 

int main() 
{ 
    thread one(add); 
    thread two(show); 

    one.join(); 
    two.join(); 
} 

在調試模式下,不存在這樣的問題。在發佈模式下,如果註釋行未註釋,則它會再次運行。但就像這樣,就有一個問題。問題是什麼?在發佈模式下,vector :: empty()函數無法正常工作

+2

您的代碼被破壞,因爲您有兩個線程操縱矢量而沒有同步。使用互斥鎖。 –

+0

但它適用於{cout <<「」;} – sunofkyuss

+1

它看起來可行,但那不可靠。嚴重的是,獲得關於多線程的教程,它會解釋一些事情。 –

回答

1

std::vector(與任何其他std::容器一樣)通常不是線程安全的。這意味着一般不支持從多個線程併發修改對同一個向量的訪問。這意味着雖然可以同時調用來自多個線程的矢量的非修改函數(例如,您可以撥打begin()end()而沒有任何問題),但修改函數應該可以獨佔訪問矢量對象。爲了實現這種獨佔性,您需要使用線程同步原語來「發信號」來獲得對向量的獨佔訪問權,執行您的修改,而不是「信號」,即獨佔訪問不再需要。

注意,當您修改(插入)數據到矢量時,這不足以執行那種例程。當您從矢量中讀取數據時,您也必須執行相同的跳舞,因爲修改需要獨佔訪問權限,甚至讀取也會違反這種排他性。我在這裏使用的非技術術語「信號」,有一個技術對應物 - 它被稱爲臨界區。在這裏,我們說你'進入關鍵部分'和'離開關鍵部分'。

有多種方式進入並離開關鍵部分。這些瑕疵是所謂的mutexes,它們應該足以讓你學習。請記住,還有其他方法,您將在適當的時候學習。