UNIX文化,提倡的是一種簡(jiǎn)潔,直觀,低復(fù)雜度的文化.
UNIX倡導(dǎo)多進(jìn)程編程,而不是大家所熟悉的多線程編程.
由于進(jìn)程有自己獨(dú)立的地址空間,因此多進(jìn)程之間的協(xié)作與交互,通關(guān)操作系統(tǒng)提供的各種IPC方法實(shí)現(xiàn).
在討論IPC的那個(gè)章節(jié)里,提出了管道,信號(hào),臨時(shí)文件,共享內(nèi)存,套接字幾個(gè)模型.
我一般寫東西玩的時(shí)候,總是喜歡建立控制臺(tái)程序,因?yàn)檩斎胼敵鰩?kù)都比較簡(jiǎn)單,并且所見即得.管道/重定向之類,都是建立在標(biāo)準(zhǔn)輸入/輸出的基礎(chǔ)上.這里所描述的管道/重定向,并不是在一個(gè)進(jìn)程中調(diào)用CreatePipe,改變管道方向,然后用CreateProcess建立一個(gè)子進(jìn)程.UNIX所用的方式類似于.bat命令,比如 dir | more,用符號(hào)"|"連接兩個(gè)進(jìn)程的管道.事實(shí)上,一般能用上管道/重定向的進(jìn)程,都是一個(gè)過濾器,數(shù)據(jù)從標(biāo)準(zhǔn)輸入進(jìn)來,經(jīng)過加工后從標(biāo)準(zhǔn)輸出跑掉.因此,管道/重定向技術(shù)對(duì)于流水線般加工的任務(wù),是一個(gè)相當(dāng)棒的模型.
需要注意的是,使用管道模型的程序,通常數(shù)據(jù)流/協(xié)議(在某個(gè)任務(wù)下)是單向的.
總體上,在WINDOWS下像UNIX那樣使用管道/重定向機(jī)制,通常是用C/C++寫許多獨(dú)立但是可以連接的程序,然后用bat的方式,將其按所需任務(wù)組合.如果希望在程序中可以像bat那樣啟動(dòng)其他進(jìn)程,只要用簡(jiǎn)單的system(command)函數(shù)就好了,WINAPI通常都是復(fù)雜而累贅的.
UNIX下的信號(hào),是對(duì)進(jìn)程發(fā)出的,由進(jìn)程的相應(yīng)回調(diào)函數(shù)處理,程序可以重載自己的實(shí)現(xiàn).這和WINDOWS下的消息比較相像,只是WM通常都需要窗口.由于信號(hào)/消息能傳遞的數(shù)據(jù)都比較薄弱簡(jiǎn)單,所以這通常作為一種輔助機(jī)制,和其他IPC模型共同協(xié)作.
臨時(shí)文件,是一種能解決雙向溝通的模型,但是并不利于做復(fù)雜的事情,最好的用途是在簡(jiǎn)單,需要雙方溝通,大數(shù)據(jù)量的情形下.使用方法大概描述為,A進(jìn)程調(diào)用執(zhí)行某個(gè)任務(wù)的B進(jìn)程,B進(jìn)程將執(zhí)行結(jié)果寫入A進(jìn)程指定的文件,A進(jìn)程使用該文件.
一個(gè)隱患是,一旦破壞程序知道臨時(shí)文件的位置,就可能破壞該文件.
其實(shí)臨時(shí)文件和接下來所說的共享內(nèi)存在功能上并無太大區(qū)別.唯一不同的是,臨時(shí)文件所使用的API,都是很容易跨平臺(tái)的.
共享內(nèi)存,是一個(gè)和操作系統(tǒng)密切相關(guān)的IPC模型,作為生產(chǎn)者/消費(fèi)者系統(tǒng)的一個(gè)性能優(yōu)化的解決方案,其最大的優(yōu)勢(shì)便是對(duì)大型數(shù)據(jù)傳遞所提供的效率.但是,預(yù)防競(jìng)爭(zhēng)/死鎖是必須考慮的問題.我覺得,由于共享內(nèi)存的API通常是專有的,不易于跨平臺(tái),所以使用共享內(nèi)存的條件應(yīng)該比較嚴(yán)格,必須要在性能需求高和一次數(shù)據(jù)交換量巨大的情況下才可以考慮,而且,臨時(shí)文件是一個(gè)可以考慮的替代模型.
套接字,是一個(gè)直觀并且在眾多操作系統(tǒng)中廣泛使用的模型,不用說也知道是一個(gè)好東西了.
在《UNIX編程藝術(shù)》中,認(rèn)為大多數(shù)的IPC方法都是可以相互替代的,因此最重要的是選擇一個(gè)盡可能使系統(tǒng)簡(jiǎn)單的模型.此外,特別說多線程不該是最先考慮到的方法,而是最后一個(gè).
多線程將子任務(wù)糅合在一個(gè)程序中,而不是分開,增加了全局復(fù)雜度.此外,多線程帶來的2個(gè)不可避免的BUG:時(shí)序問題,還有競(jìng)爭(zhēng)/死鎖的問題.縱然全局變量提升了任務(wù)之間的溝通效率,但是通常這種效率都被昂貴的鎖定/解鎖所抵消了.
特別是,使用多線程的程序所依賴的庫(kù),并非都是線程安全的,其中一旦產(chǎn)生的問題,會(huì)使得你麻煩重重,特別是,多線程的程序調(diào)試......由于時(shí)序問題,你自己想想都知道了.
因此,非要使用多線程,理想(意味著不可能存在)的約束是,線程盡量不使用全局變量;每個(gè)變量只被一個(gè)線程使用;被線程使用的變量不再被主進(jìn)程使用;線程中不使用static變量.....這種約束,根本沒有辦法實(shí)現(xiàn)嘛.
posted on 2006-08-13 11:06
LOGOS 閱讀(2312)
評(píng)論(8) 編輯 收藏 引用 所屬分類:
《UNIX編程藝術(shù)》讀書筆記