1. 程式人生 > >多程序與多執行緒(六)--LinuxThreads(轉)

多程序與多執行緒(六)--LinuxThreads(轉)

(注:這篇文章轉自網路,雖然Linux從核心2.6開始,多執行緒已使用NPTL技術,但是這篇文章對我們理解多執行緒技術還是挺有用的)

Linux核心對多程序和多執行緒的支援方式:

        執行緒機制支援併發程式設計技術,在多處理器上能真正保證並行處理。而在linux實現執行緒很特別,linux把所有的執行緒都當作程序實現。linux下線 程看起來就像普通程序(只是該程序和其他程序共享資源,如地址空間)。上述機制與Microsoft windows或是Sun Solaris實現差異很大。

        Linux的執行緒實現是在核外進行的,核內提供的是建立程序的介面do_fork()。核心提供了兩個系統呼叫__clone()和fork(),最終都 用不同的引數呼叫do_fork()核內API。 do_fork() 提供了很多引數,包括CLONE_VM(共享記憶體空間)、CLONE_FS(共享檔案系統資訊)、CLONE_FILES(共享檔案描述符表)、 CLONE_SIGHAND(共享訊號控制代碼表)和CLONE_PID(共享程序ID,僅對核內程序,即0號程序有效)。當使用fork系統呼叫產生多程序 時,核心呼叫do_fork()不使用任何共享屬性,程序擁有獨立的執行環境。當使用pthread_create()來建立執行緒時,則最終設定了所有這 些屬性來呼叫__clone(),而這些引數又全部傳給核內的do_fork(),從而建立的”程序”擁有共享的執行環境,只有棧是獨立的,由 __clone()傳入。

         即:Linux下不管是多執行緒程式設計還是多程序程式設計,最終都是用do_fork實現的 多程序程式設計,只是程序建立時的引數不同,從而導致有不同的共享環境。Linux執行緒在核內是以輕量級程序的形式存在的,擁有獨立的程序表項,而所有的創 建、同步、刪除等操作都在核外pthread庫中進行。pthread 庫使用一個管理執行緒(__pthread_manager() ,每個程序獨立且唯一)來管理執行緒的建立和終止,為執行緒分配執行緒ID,傳送執行緒相關的訊號,而主執行緒pthread_create()) 的呼叫者則通過管道將請求資訊傳給管理執行緒。

很多朋友都說使用多執行緒的好處是資源佔用少,其隱含之意就是說程序佔用資源比執行緒多,對吧?但實際上Linux下多程序是否就真的點用很多資源呢? 暫且不說程序是否比執行緒佔用資源多,就程序佔用資源的多少情況而言,Linux確實是做得相當節省的。產生一個多程序時肯定是要產生的一點記憶體是要複製進 程表項,即一個task_struct結構,但這個結構本身做得相當小巧。其它對於一個程序來說必須有的資料段、程式碼段、堆疊段是不是全盤複製呢?對於多 程序來說,程式碼段是肯定不用複製的,因為父程序和各子程序的程式碼段是相同的,資料段和堆疊段呢?也不一定,因為在Linux裡廣泛使用的一個技術叫 copy-on-write,即寫時拷貝。copy-on-write意味著什麼呢?意味著資源節省,假設有一個變數x在父程序裡存在,當這個父程序建立 一個子程序或多個子程序時這個變數x是否複製到了子程序的記憶體空間呢?不會的,子程序和父程序使用同一個記憶體空間的變數,但當子程序或父程序要改變變數x 的值時就會複製該變數,從而導致父子程序裡的變數值不同。父子程序變數是互不影響的,由於父子程序地址空間是完全隔開的,變數的地址可以是完全相同的

          Linux的”執行緒”和”程序”實際上處於一個排程層次,共享一個程序識別符號空間,這種限制使得不可能在Linux上實現完全意義上的POSIX執行緒機 制,因此眾多的Linux執行緒庫實現嘗試都只能儘可能實現POSIX的絕大部分語義,並在功能上儘可能逼近。Linux程序的建立是非常迅速的。核心設計 與實現一書中甚至指出Linux建立程序的速度和其他針對執行緒優化的作業系統(Windows,Solaris)建立執行緒的速度相比,測試結果非常的好, 也就是說建立速度很快。由於非同步訊號是核心以程序為單位分發的,而LinuxThreads的每個執行緒對核心來說都是一個程序,且沒有實現”執行緒組”,因 此,某些語義不符合POSIX標準,比如沒有實現向程序中所有執行緒傳送訊號,README對此作了說明。LinuxThreads中的執行緒同步很大程度上 是建立在訊號基礎上的,這種通過核心複雜的訊號處理機制的同步方式,效率一直是個問題。LinuxThreads 的問題,特別是相容性上的問題,嚴重阻礙了Linux上的跨平臺應用(如Apache)採用多執行緒設計,從而使得Linux上的執行緒應用一直保持在比較低 的水平。在Linux社群中,已經有很多人在為改進執行緒效能而努力,其中既包括使用者級執行緒庫,也包括核心級和使用者級配合改進的執行緒庫。目前最為人看好的有 兩個專案,一個是RedHat公司牽頭研發的NPTL(Native Posix Thread Library),另一個則是IBM投資開發的NGPT(Next Generation Posix Threading),二者都是圍繞完全相容POSIX 1003.1c,同時在核內和核外做工作以而實現多對多執行緒模型。這兩種模型都在一定程度上彌補了LinuxThreads的缺點,且都是重起爐灶全新設 計的。

          綜上所述的結論是在Linux下程式設計多用多程序程式設計少用多執行緒程式設計

         IBM有個傢伙做了個測試,發現切換執行緒context的時候,windows比linux快一倍多。進出最快的鎖(windows2k的 critical section和linux的pthread_mutex),windows比linux的要快五倍左右。當然這並不是說linux不好,而且在經過實際 程式設計之後,綜合來看我覺得linux更適合做high performance server,不過在多執行緒這個具體的領域內,linux還是稍遜windows一點。這應該是情有可原的,畢竟unix家族都是從多程序過來的,而 windows從頭就是多執行緒的。

如果是UNIX/linux環境,採用多執行緒沒必要。

多執行緒比多程序效能高?誤導!

應該說,多執行緒比多程序成本低,但效能更低

在UNIX環境,多程序排程開銷比多執行緒排程開銷,沒有顯著區別,就是說,UNIX程序排程效率是很高的。記憶體消耗方面,二者只差全域性資料區,現在記憶體都很便宜,伺服器記憶體動輒若干G,根本不是問題。

多程序是立體交通系統,雖然造價高,上坡下坡多耗點油,但是不堵車。

多執行緒是平面交通系統,造價低,但紅綠燈太多,老堵車。

我們現在都開跑車,油(主頻)有的是,不怕上坡下坡,就怕堵車。

高效能交易伺服器中介軟體,如TUXEDO,都是主張多程序的。實際測試表明,TUXEDO效能和併發效率是非常高的。TUXEDO是貝爾實驗室的,與UNIX同宗,應該是對UNIX理解最為深刻的,他們的意見應該具有很大的參考意義

注:

關於那個critical section和pthread_mutex_t,critical section本質上是一個自旋鎖,短期鎖當然快,要比也該是和pthread_spinlock_t比。

mutex和critical section的確是不能比的。一個涉及到核心,一個沒有涉及到核心。


轉自http://www.soft-bin.com/html/2010/07/09/%E5%A4%9A%E8%BF%9B%E7%A8%8Bvs%E5%A4%9A%E7%BA%BF%E7%A8%8B%EF%BC%8C%E4%B8%80%E4%B8%AA%E9%95%BF%E6%9C%9F%E7%9A%84%E4%BA%89%E8%AE%BA.html,貌似他也是轉別人的。 

轉自:http://blog.chinaunix.net/uid-20556054-id-3068371.html