2012-02-21 76 views
0

問候!!不使用互斥體保護雙var

我有AC AP在Linux上運行這是一個多線程POSIX應用, 在線程1,我設置這樣的全局變量:

Pthread_mutex_lock(&Mutex1); 
for(idx=0;idx<1000;idx++) 
{ 
     Data1[idx].doubleval = idx * 100.0 * anothervar ; 
}//for 
Pthread_mutex_unlock(&Mutex1); 
在線程2

,我得到這樣的全局變量它:

Pthread_mutex_lock(&Mutex1); 
for(idx=0;idx<1000;idx++) 
{ 
    doublexxx = Data1[idx].doubleval ; 
    DoSomething(doublexxx) ; 
}//for 
Pthread_mutex_unlock(&Mutex1); 

現在,假設我不希望在我的AP使用互斥,這在線程正在設置數據1 [33] .doubleval同時線程2正在讀取數據1 [33] .doubleval,將數據1 [33]。 doubleval是一個非常奇怪的值?我的意思是,例如,double var有4個字節,而thread1正在設置Data1 [33] .doubleval前2個字節,而不是後面2個字節,在這個組件中 thread2試圖讀取Data1 [33] .doubleval ... 。可能嗎 ?

如果可能的話,我該怎麼做才能在沒有這種問題的情況下保護double var? 互斥是很好用,我只是想知道是否有另一種方式來保護雙線var 其中thread1正在寫入,至少thread2嘗試讀取相同的變量 將等待4個字節雙var完成!

+1

只需使用互斥鎖,你不必擔心它。爲什麼不想要不必要地創建問題? – 2012-02-21 05:20:16

+0

認真;如果你不想鎖定,那麼你不應該使用線程。 – tbert 2012-02-21 06:40:05

+0

謝謝,我的應用程序使用了太多的線程,並且我想盡可能快地運行,我不知道mutex_lock如何影響性能,實際上所有互斥量都用在一個小內存strcpy塊中,但我仍然被告知要使它運行得更快....感謝所有善意的答覆! – barfatchen 2012-02-21 09:20:27

回答

1

是否可以讀取「部分寫入」值取決於大量因素(例如目標系統和對齊方式),並且絕對不是可移植的。舉個例子,假設這個代碼運行在一個16位的CPU上,並且在軟件中模擬了浮點支持。

即使使用互斥鎖,第二個線程的行爲仍然是未定義的,因爲它不知道它是在第一個線程寫入數據之前還是在第一個線程寫入數據之後讀取了數據。

我懷疑你的設計存在更高層次的問題 - 也許你應該使用一個條件變量來讓第二個線程等到第一個線程寫入。

我還懷疑你提出刪除互斥鎖的原因是爲了提高可伸縮性/性能。例如,讓一個線程使用數組的一部分,而另一個線程修改同一數組的完全不同的部分。如果這是你的問題背後的原因,那麼解決方案取決於你的方案 - 它可以像使用多個鎖一樣簡單(每個區域的一個互斥鎖,每個條目最多一個互斥鎖),但可能意味着實現一個「讀取器/ writer「鎖(以便多個線程同時允許從數組中讀取,只要沒有其他線程正在寫入)。

+0

Thanks ... Thread1在無限循環中寫入數據,Thread2在無限循環中讀取數據,我的目標是獲得更多的性能,我所關心的是thread2不會得到奇怪的值,如果該值是正確的值,無論thread1寫它快或慢,然後我不會使用互斥...因爲thread2只需要一個合理的值asap,我最害怕的是thread2讀取一個不合理的值,就像我說的2個字節寫在thread1中,而不是完成在稍後的2個字節中 – barfatchen 2012-02-21 05:52:20

1

需要擔心的問題不是通過寫入中途讀取的值;我不知道這是可能的系統。問題是你的第二個線程的行爲將是未定義的,因爲你不知道它會在第一個線程寫入給定的內存段之前還是之後讀取。如果沒有互斥體,或者功能上相同的東西,就沒有辦法獲得明確定義的行爲。

+0

在Alpha處理器上肯定會發生字撕裂。在x86 CPU上,我相信它只能發生在未對齊的訪問上,假設編譯器沒有做任何有趣的事情。(例如,GCC有時會在讀取數據後將值寫回內存,即使代碼不會更改該值也會導致另一個線程寫入數據丟失。) – 2012-02-21 05:46:31

+0

假設線程2始終讀取全局雙變量g1哪個thread1總是寫入,這兩個線程都處於無限循環中,如果g1現在是1.55,並且thread1將執行g1 = 1.66,如果thread2要在沒有互斥鎖的同一個monent上讀取g1,如果我可以確定g1必須= 1.55或1.66,沒有其他值可能,那麼我想我會避免互斥! – barfatchen 2012-02-21 07:52:37