由於linux對執行緒實現的一些特殊性,所以會給我們理解執行緒及其相關的一些函式帶來疑惑,這裡做個解答:
1、關於sleep
很多書籍上都說sleep這個系統呼叫會使整個程序sleep,而不單是sleep乙個執行緒。這樣說沒錯,但我們要是在linux下寫乙個多執行緒 的程式,在乙個執行緒中呼叫sleep,你會發現其他執行緒照樣執行,這是怎麼回事呢?這就是由於linux下的執行緒,其實執行緒的註冊、銷毀等工作是在 pthread庫裡面,而在核心中,執行緒其實就是乙個程序。linux對執行緒的實現是通過__clone呼叫實現的,這個呼叫會new多個程序出來,只不 過的是, linux會設定這些程序的共享記憶體空間、檔案描述符等屬性為相同,這樣就實現了執行緒的定義(共享乙個程序的記憶體空間、執行緒切換不需要切換上下文環 境......)。所以,很多書籍上會說linux的執行緒在核內是輕量級的程序,就是這個道理。因為和普通程序相比,linux的執行緒在核內就是一些被設 置了很多屬性的程序,從而實現了執行緒。
所以,在linux下,乙個執行緒呼叫了sleep,反映到核內就是sleep了乙個輕量級程序,自然其他的執行緒(核內的輕量級程序)不受影響,照 樣可以run了。簡言之,之所以sleep乙個執行緒,其他執行緒仍然可以執行,這是因為在linux下,執行緒和程序不是n對1的,而是1對1的。
2、有關執行緒的排程
有了1的描述,我們就清楚的知道了,其實linux對執行緒的排程,策略和程序是基本一致的。所以,很多人問,為什麼乙個執行緒中如果有乙個迴圈的 話,其他執行緒都得不到執行,這就是因為linux對執行緒的排程,策略和程序是一樣的,即,如果乙個執行緒處於乙個高密度的工作狀態的話,或者該執行緒的cpu slice沒用完的話,這個執行緒是不會被排程的。有關這個問題,還可以參看本論壇中「有關執行緒切換的乙個問題」一帖。
其實說白了,明白了第一點的話,很多linux執行緒的問題就迎刃而解了。
有關linux下執行緒的實現方式,再附上一段「posix執行緒程式設計指南」(來自ibm developworks)中的描述,這段描述很專業,很到位:
我們知道,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執行緒在核內是以輕量級程序的形式存在的,擁有獨立的程序表項,而所有的建立、同步、刪除等操作都在核外 pthread庫中進行。pthread庫使用乙個管理執行緒(__pthread_manager(),每個程序獨立且唯一)來管理執行緒的建立和終止,為 執行緒分配執行緒id,傳送執行緒相關的訊號(比如cancel),而主線程(pthread_create())的呼叫者則通過管道將請求資訊傳給管理執行緒。
Linux下執行緒
此文講述的執行緒為linux下,其執行緒庫函式是由posix標準定義的,稱為posix thread或者pthread。在linux上線程函式位於libpthread共享庫中,因此在編譯時要加上 lpthread選項。建立執行緒 終止執行緒 等待執行緒 三個函式都為pthread.h中定義,其中要注...
有關執行緒排程問題
有關執行緒排程問題 下列關於執行緒排程的敘述中,錯誤的是 e a.呼叫執行緒的sleep 方法,可以使比當前執行緒優先順序低的執行緒獲得執行機會 b.呼叫執行緒的yield 方法,只會使與當前執行緒相同優先順序的執行緒獲得執行機會 c.當有比當前執行緒優先順序高的執行緒出現時,高優先順序的執行緒將搶...
Linux下執行緒的排程策略與優先順序
linux核心的三種排程策略 1,sched other 分時排程策略,2,sched fifo實時排程策略,先到先服務。一旦占用cpu則一直執行。一直執行直到有更高優先順序任務到達或自己放棄 3,sched rr實時排程策略,時間片輪轉。當程序的時間片用完,系統將重新分配時間片,並置於就緒佇列尾。...