2013-07-17 73 views
0

我想在C++中模擬競爭條件。下面是我的代碼,我使用了Xcode作爲我的IDE競爭條件模擬崩潰在xcode

相關的代碼是這樣的:

int main(int argc, const char * argv[]) 
{ 
int value=0; 
int* ptr = &value; 

racer r1(ptr, "John"); 
racer r2(ptr, "Mike"); 

std::thread my_thread1(r1); 
std::thread my_thread2(r2); 

//guard g1(my_thread1); 
//guard g2(my_thread2); 

my_thread1.join(); 
my_thread2.join(); 

cout<<"result:= "<<*ptr<<endl; 
cout <<"end!"<<endl; 
return 0; 

}

,爲賽車手,我有:

racer::racer(int* r, char const* name) 
{ 
    this->r=r; 
    this->name=name; 
} 

void racer::print_result() 
{ 
    cout<<this->name<<" "<<*r<<endl; 
} 

void racer::count_now() 
{ 
    for (int i = 0; i < 50; i++) 
    { 
     *r = *r + 1; 
     cout<<this->name<<". "<<*r<<endl; 
    } 
} 


void racer::operator()() 
{ 
    count_now(); 
} 

所以基本上,沒有競爭我的預期結果是* ptr = 100,因爲有2個線程在同一資源上一起運行。所以有時當我運行它時,我得到了100,有時它崩潰了,我得到下面的錯誤信息。這是爲什麼?換句話說,爲什麼我不能得到大於100的值?當它崩潰是否意味着我有一個競爭條件,從而出現錯誤?

enter image description here

+0

代碼在我的linux上工作正常。 – ROTOGG

+0

@Leon Li您是否得到了> 100的結果? – adhg

回答

1

首先對於簡單的問題:由於您使用的Xcode我假設你使用一個基於x86的處理器。我的理解是,您將無法按照您嘗試這樣做的方式產生簡單的數據競爭,因爲基於x86的Intel處理器實現了強大的高速緩存一致性協議,更確切地說是MESI protocol。在不同的系統上,如果緩存一致性協議較弱,例如在基於ARM的處理器上,我認爲你會得到有趣的值,但目前我無法嘗試。

更難的問題是:它爲什麼會崩潰?調試器清楚地顯示IOStreams庫中的崩潰,這似乎是由於同時訪問std::cout而導致的。但是,在調試器指向的線上,我無法真正看到空指針取消引用的來源。解除引用的唯一指針是this(函數std::basic_streambuf<...>::overflow()是一個virtual函數,即需要訪問虛函數表)。

1

您的示例代碼不太可能產生競爭條件。競爭條件的前提是線程間的上下文切換。你的例子太簡單了

1) only two threads. 
2) Each thread, on linux, by default, gets about 50ms CPU time for each context switch. 

你的代碼只有50(增量+ cout)。這50個循環可以在50ms內輕鬆完成,因此兩個線程都可以在執行時無需任何上下文切換的情況下完成。沒有(足夠的)上下文切換,你將不會見證任何競賽狀態。

增加成功的機會:

1) start 50 threads. 
2) each thread execute 50 loops. 
3) each loop does 10 increments. 

或增加1號)2)3),直到你開始看到許多上下文切換,並希望導致競爭條件。一個前兆將是輸出消息混合(「約翰」,「邁克」...)