選擇虛擬機環境介入多線程編程是一個好的選擇
多核處理,并行設計已經成為了計算機發展不可阻擋的趨勢之一。越來越多的技術人員開始關注多線程程序設計。但是選擇什么樣的環境來介入多線程程序設計往往是一個比較頭疼的問題。應該說,目前的許多環境并沒有為多線程建立良好的模型,例如C和C++。為此,人們試圖在這種環境中通過添加庫的方式為其加入多線程的功能。但是,這顯然是不合適的,實際上許多的時候,程序庫根本不能解決所有的問題,我們真正需要的是一種將多線程納入其規范體系之內的環境。
我們在C/C++中編寫多線程程序依靠的往往不是嚴謹的定義與標準約束,而是經驗占據了主要的部分。我們的多線程代碼并沒有較廣的適用性,而是在嚴重的依賴于編譯器文檔中提供的編譯器的提供的內存模型信息。并且您需要時刻小心的處理編譯器Optimization帶來的影響。這使得多線程代碼在這種語言下變得非常難看。我們不僅僅要考慮操作系統的問題,處理器體系的問題,甚至要考慮各種編譯器的支持問題。書寫過多線程庫的技術人員也許會對漫天飛舞的Macro Definition感到一種前所未有的滿足感,而維護人員則叫苦不迭。當然,你可能說,這種事情永遠不會在你身上發生,因為你為Microsoft工作,你只為Windows寫程序,你只使用Visual C++編譯器,并且你永遠不會使用除了Intel之外的處理器。
拿一個例子來說[1]
Thread 1:
if (x == 1) ++y
Thread2:
if (y == 1) ++x;
假設x和y一開始均初始化為0,那么這個程序會有數據競爭嗎?從上述來看也許不會吧,如果他們就是像寫的那樣執行的話,但是有一個問題,編譯器也許會對單線程優化為:
Thread 1:
++y; if (x != 1) --y;
Thread 2:
++x; if (y != 1) --x;
可能這種優化有些傻(或者說,根本不是優化),但是僅僅就一個例子而言已經足夠了。也就是,編譯器不會對你的代碼負責,并且也沒有必要,因為編譯器本來就沒有違反標準。標準中對線程的行為幾乎只字未提。
文獻[1]中另外有一個例子:
struct { int a:17; int b:15 } x;
實際上,沒有一款處理器可以直接處理17位的讀寫工作,因此類似于x.a = 42之類的操作實際上是這樣完成的:
{
tmp = x; // Read both fields into
// 32-bit variable.
tmp &= ~0x1ffff; // Mask off old a.
tmp |= 42;
x = tmp; // Overwrite all of x.
}
而這在多線程環境下就引入了潛在的競爭!
還有幾個非常經典的問題那就是volatile是什么東西?sequence point又是什么東西?答案是,沒有人說得清楚。
好了,你可能說,那怎么解決這些問題呢。根本的答案應該是,在新標準中慎重考慮這些事情!考慮共享內存多線程模式下的內存模型以及線程行為。眾所周之,ISO C++委員會是一個官僚組織,就像OpenGL對于DirectX一樣,任何事情的決定都是緩慢而困難的。尤其對于有大批大批遺留代碼的C++更是如此!舉個例子,我們可不可以像java或者.net一樣將volatile讀寫賦予某種語義呢,例如acquire,release或者total order(雖然這很不可思議),看起來不錯,但是不要忘記了,大批大批的volatile存在于遺留的代碼中,這種memory fence的引入會讓原有的代碼在重新編譯之后產生很大的性能下降(你知道interlockedXxx以及類似操作會多花多少個時鐘周期嗎?很驚人的哦),這是人們不能接受的,因此他們正在討論引入atomic library從另一個角度解決這個問題。
因此,我們的結論是,如果你希望入手多線程編程,應當找到一個內存模型完備(基本完備,我的意思是)的環境來入手,虛擬機環境(Java,.NET)是一個不錯的選擇。當然,我們應該時刻跟蹤C++的發展,為將來做好準備,畢竟它是一個有著悠久歷史的,有著大批擁躉的,非常有魅力的語言!
附:C++ 0x標準中關于內存模型的討論參見:
http://www.open-std.org/ 網站上WG21的以下文檔:
N1680, N1777, N1876, N1911, N1942, N1947, N2010, N2016, N2052, N2075, N2138, N2153, N2171, N2176, N2177, N2197, N2237, N2300, N2334, N2338, N2359, N2360, N2361, N2429, N2480, N2492, N2493, N2556, N2664
(注:上述文獻追蹤已經更新到2008年6月)
參考文獻:
[1] Hans-J. Boehm,Threads Cannot be Implemented as a Library,Internet Systems and Storage Laboratory,HP Laboratories Palo Alto,November 12, 2004
多核處理,并行設計已經成為了計算機發展不可阻擋的趨勢之一。越來越多的技術人員開始關注多線程程序設計。但是選擇什么樣的環境來介入多線程程序設計往往是一個比較頭疼的問題。應該說,目前的許多環境并沒有為多線程建立良好的模型,例如C和C++。為此,人們試圖在這種環境中通過添加庫的方式為其加入多線程的功能。但是,這顯然是不合適的,實際上許多的時候,程序庫根本不能解決所有的問題,我們真正需要的是一種將多線程納入其規范體系之內的環境。
浙公網安備 33010602011771號