2017-02-23 68 views
0

我做了它具有以下特點的程序:C++優化導致螺紋鎖固

這是工作中的一類ClassA的

變量:

int8_t* p1; // this is only modified on thread1 
volatile int8_t* p2; 

線程1(其被鎖定)

while(p1 + 64 > p2); 

線程2(其修改P2)

while(true) { 
    //reading file 
    p2 += 10; 
    //reading file 
    p2 += 10; 
    //reading file 
    p2 += 10; 
} 

Thread1在某個點被鎖定。但是,將thread1更改爲下面的代碼會使thread1永遠不會被鎖定。

while(p1 + 64 > p2) { 
    printf("%d\n", p1); 
} 

我編譯了這段代碼-Ofast。我想問題是優化。我如何解決這個問題而不修改我的編譯器標誌?

+1

不要使用volatile來進行線程同步。 – knivil

回答

3

要麼使用互斥量,要麼對p1p2使用適當的原子類型。在C++中,volatile沒有定義的多線程語義。修改常規變量(如p2),而另一個線程可能正在訪問它會產生不可預知的結果。不要這樣做。

+0

我在代碼上犯了一個錯誤。 volatile變量是p2而不是p1 – McD0n3ld

+0

它沒有太大區別。不要使用'volatile'。使用原子類型或互斥體。 –

-1

p2是您在第一個線程之外修改的變量,因此應聲明爲volatile。

即便如此,寧願使用原子或互斥體。易失性不能保護無序讀寫。在linux上,當沒有爭用時,互斥體非常便宜。

+0

volatile與線程間的數據同步無關。 –

+0

Volatile告訴編譯器,內存地址範圍可以在當前的外部修改,不管是由硬件,操作系統還是其他線程修改。所以雖然它的使用是不可取的,但在這種情況下可能會有所幫助。 – doron

+0

當然,在這種情況下,volatile可能會有所幫助:它可能暫時隱藏真正的問題,當然,這意味着當您爲最重要的客戶演示代碼時,真正的問題會顯現出來; 「好吧,它曾經工作過」不會是一個可以接受的迴應。 –