轉自: http://m.blog.chinaunix.net/uid-29131868-id-5155428.html
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理解最為深刻的,他們的意見應該具有很大的參考意義。