同事說omni_thread為什麼要搞得那麼複雜呢?對了,先問一下,你有沒有用過這個類?其實,這就是一個對系統線程對象Thread的抽象,以使應用程式可以在不同平台上方便移植,而不論底層具體的執行緒模式。
起初,這個世界是沒有Thread這個概念的,只有Process。我們知道,當初作業系統就是用Process來抽象計算任務的,並負責對Process進行調度。對於單CPU系統,一個時間裡只有一個Process能佔有CPU而得以執行。後來,不知道從什麼時候開始,人們發明了Thread這個概念,Thread就是表示CPU的調度。兩者的區別就是,Process是一個實體,包括了具體的代碼,而Thread表示的是CPU的調度。
我們知道,代碼即使裝載進了記憶體裡,而沒有被CPU執行也是沒有任何意義的。而CPU怎樣才能執行代碼呢?是的,你必須把下一句執行指令的代碼指向你的代碼。那麼是誰讓它去呢?是作業系統。那作業系統怎麼讓它去呢?這裡有必要先說明一下,現在的作業系統都是多任務的系統。所謂的多任務就是說,同時可以運行多個Process。它如何做到有條不紊的來回切換呢?打個比喻,CPU執行代碼就像沿著一條線(Thread)移動,雖然這條線有可能彎彎曲曲繞來繞去的,但終究還是一條線.那麼,運行多個Process,就要有很多條線。這就像彈中國古箏一樣,只是這裡你就是作業系統。什麼時候發什麼音,要看你當時把手指放在什麼弦上了。聲音是因弦動而起的,而音色則由弦所處位置決定。
所以,Thread就是作業系統放在你的代碼裡的那個弦,代碼因弦而動。作業系統的任務調度歸根到底就是對Thread的調度。
好了,扯遠了,再回到開頭的問題。omni_thread的存在是不是就是因為不同作業系統對琴弦的操作不同啊?嗯,這就像古箏和吉他的區別,而且你能認為鋼琴的琴鍵不是另一種弦嗎?所以讓程式員寫跨平台的程式,就像讓音樂家同時熟悉多種樂器一樣困難。omni_thread就是要讓所有Thread的操作在不同的作業系統上都一樣。如果樂器也能有這樣一個統一介面,一個人熟練掌握多種樂器就根本不是問題了。要不怎麼說,開發軟體是高科技呢,哈哈。
另外,Thread的操作實在是一件複雜的事情,不僅在不同平台上,就是在同一個平台上也是如此的。如何在不同的Thread之間保持同步是很複雜的--想想看,女孩子織毛衣,如何穿針是很講究的。而CPU每秒鐘運行百萬行的指令,可不容你慢慢想。一不小心就會纏線,或紮到手啦。
說了那麼多,根本還沒有到我想要說的,很晚了,趕緊打住。我們前面說了,代碼本身是死的,只有被CPU執行了才會活起來。而要被CPU執行,就要讓Thread穿過。好了,現在我們都說物件導向編程,把世界都用Class來抽象,用Object來表示實體。但是說到底,Object也是代碼,根本就是死的。就像木偶一樣,如果沒有一根Thread拴著就會耷拉下去!對於大部分的Object來說,大部分時間裡它都是死的,只有Thread穿過的瞬間才會靈光一閃。那麼怎樣讓一個Object永葆青春,光芒四射呢?答案就是,用一個Thread永遠拴著它。這樣它就可以在那裡不停跳動,它活了!
omni_thread就是這樣一個帶Thread的木偶,一旦栓動就活起來了。當然,這隻是一個傀儡,你需要在上面依附你的實體,也就是你的代碼。現在,你看上去就像一個天使了,會煽動翅膀的天使!
其實,很多類庫裡都有這樣的Thread封裝類。比如Java裡的Runnable,.NET裡的Thread,MFC裡的CWinThread,都是同一個東西。我個人最喜歡的就是Java裡的叫法,Runnable多形象啊!
當然,我也看到很多C++的程式員根本就不用上面的什麼omni_thread,而直接用pthread_create(),CreateThread()自己去引線拴木偶。雖然麻煩點,但是人家樂意嘛。
最後推薦一篇文章《白話面向智能體編程》,就是講的如何讓OOP變得更自然,那就是AOP。這裡的Object變成了Agent,也就是由一個死的東西,變成了一個活物。這不由讓我想起了中國古代哲學家王陽明,他好像說過這樣的話,“花兒之所以存在是因為我在看它”。很唯心是不是?但是現在的OOP就是這樣的,如果你不去運行它,它就真的不會動啊!Agent就不一樣了,你愛看不看,我都在那裡愛怎麼動怎麼動。文章裡關於“燒雞塊”的比喻實在是精闢!雖然現在禽流感流行,不過只看看也無妨吧。