日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

上一節(jié)從C語言源代碼層面較為詳細的討論了linux創(chuàng)建進程的過程,其實就是創(chuàng)建進程運行所需的內(nèi)存空間,填充描述進程的 task_struct 結(jié)構(gòu)體,以及加載進程的程序而已。

Linux是如何創(chuàng)建線程的呢?

Linux 內(nèi)核并無專門創(chuàng)建線程的機制

我們之前提到,Linux并不特殊對待線程,在Linux看來,線程不過就是一種特殊的進程而已。那么,Linux是如何創(chuàng)建線程的呢?

線程機制是大多數(shù)現(xiàn)代編程語言都會提供的機制,該機制允許在同一進程的共享內(nèi)存地址空間運行一組“特殊的進程(即線程)”。這些線程不僅共享同一段內(nèi)存空間,還可以共享已經(jīng)打開的文件,統(tǒng)計量等其他資源。線程機制支持程序并發(fā)運行,在多處理器核心的系統(tǒng)上,該并發(fā)機制能夠?qū)崿F(xiàn)多條線程同時運行。

Linux 管理線程的方式不同于其他一些經(jīng)典操作系統(tǒng),Linux 并沒有線程的概念,它把線程當作進程的一個子集來管理。因此,Linux 內(nèi)核并未為線程提供額外調(diào)度算法,也沒有提供額外的數(shù)據(jù)結(jié)構(gòu)用于描述和存儲線程。

Linux和Windows兩種風格的操作系統(tǒng),創(chuàng)建線程的方式有何不同?

Linux 并沒有線程的概念

就像進程一樣,Linux 使用 task_struct 結(jié)構(gòu)體描述和記錄線程,每個線程都有唯一屬于自己的 task_struct 結(jié)構(gòu)。從這個角度來看,線程就是一個普通的進程,只不過線程可能和其他進程共享一些資源而已。

以 windows 為代表的一些操作系統(tǒng)提供了專門用于創(chuàng)建線程的機制,在這些系統(tǒng)中,線程常常被稱作“輕量級進程”,因為相對于進程而言,線程耗費的資源較少,能夠較為迅速的創(chuàng)建和投入運行。

但是對于 Linux 而言,線程不過是進程之間共享資源的一種手段罷了。那么是不是 Linux 中的線程比 Windows 中的線程更加“重量級”呢?也不是,因為 Linux 中的進程本身就很輕量級,Linux 創(chuàng)建進程所需時間,并不比 Windows 創(chuàng)建線程所需時間多多少。

從C語言代碼層面來看,假設(shè)某個進程包含 4 個線程,以 Windows 為代表的一些操作系統(tǒng)一般會有一個包含指向 4 個不同線程的指針的進程描述符,負責描述地址空間、打開的文件等共享資源,而線程本身再去描述自己獨占的資源。

Linux 的做法很高雅

與之對應(yīng)的,Linux 的做法很高雅,它僅需為這 4 個線程創(chuàng)建 4 個 task_struct 結(jié)構(gòu)體,然后在 task_struct 中指定它們共享的資源就可以了。

創(chuàng)建線程

看了我最近幾篇文章的讀者應(yīng)該已經(jīng)明白,Linux 內(nèi)核中的線程其實就是進程,因此線程的創(chuàng)建與進程的創(chuàng)建過程是類似的,從C語言源代碼層面看,基本上也是通過 fork() 函數(shù)和 exec() 函數(shù)族實現(xiàn)的。只不過在調(diào)用 clone() 函數(shù)時需要傳遞一個參數(shù)用于描述共享資源,例如:

clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0);

上面這行C語言代碼和調(diào)用 fork() 函數(shù)的結(jié)果差不多,只不過輸入的幾個參數(shù)標志位說明了子進程與父進程共享一些資源:地址空間、文件系統(tǒng)、打開的文件、信號處理程序。

Linux 內(nèi)核線程

對比一下,fork() 基本上就相當于 clone(SIGCHLD, 0),這也是 fork() 函數(shù)創(chuàng)建的子進程之后不再與父進程共享資源的原因。

關(guān)于 clone() 函數(shù)的參數(shù)標志位,可以在Linux中輸入 man 命令查看。

Linux 內(nèi)核線程

就像用戶空間的C語言程序開發(fā)一樣,Linux 內(nèi)核也經(jīng)常需要在后臺處理數(shù)據(jù),這時就需要借助內(nèi)核線程了。Linux 的內(nèi)核線程一般不會獨立的地址空間,它們只在內(nèi)核空間運行,不會切換到用戶空間。不過調(diào)度是和普通進程一樣的,可以被調(diào)度和搶占。

Linux 創(chuàng)建內(nèi)核線程由 kthread_create() 函數(shù)實現(xiàn),它的C語言源代碼如下,請看:

Linux和Windows兩種風格的操作系統(tǒng),創(chuàng)建線程的方式有何不同?

kthread_create() 函數(shù)的C語言源代碼

可見,kthread_create() 函數(shù)的C語言代碼并不長,而且也可以看出,Linux 內(nèi)核線程是通過 kthread_create_info 結(jié)構(gòu)體描述的,它的定義C語言代碼如下,可見,內(nèi)核線程的描述和存儲也是包含 task_struct 結(jié)構(gòu)體的:

Linux和Windows兩種風格的操作系統(tǒng),創(chuàng)建線程的方式有何不同?

包含 task_struct 結(jié)構(gòu)體

kthread_create() 函數(shù)創(chuàng)建名為 namefmt 的線程,不過線程被創(chuàng)建后是處于不可運行狀態(tài)的,我們可以通過 wake_up_process() 函數(shù)喚醒它。當然,也可以通過 kthread_run() 方法實現(xiàn)這一過程,相關(guān)的C語言代碼如下,請看:

Linux和Windows兩種風格的操作系統(tǒng),創(chuàng)建線程的方式有何不同?

相關(guān)的C語言代碼

其實就是將 kthread_create() 函數(shù)和 wake_up_process() 函數(shù)組合到一起而已。Linux 的內(nèi)核線程被啟動后,會一直運行到調(diào)用 do_exit() 退出。我們也可以調(diào)用 kthread_stop() 函數(shù)提前結(jié)束它,相關(guān)的C語言代碼如下,請看:

Linux和Windows兩種風格的操作系統(tǒng),創(chuàng)建線程的方式有何不同?

kthread_stop() 函數(shù)

kthread_stop() 函數(shù)接收的參數(shù)為 kthread_create() 函數(shù)創(chuàng)建的結(jié)構(gòu)體的 task_struct 成員。從C語言代碼可以看出,kthread_stop() 其實也是會調(diào)用 wake_up_process() 函數(shù)喚醒線程的,它在喚醒線程后,會等待線程函數(shù)退出,并不會調(diào)用 threadfn() 函數(shù)。

這里需要注意,如果創(chuàng)建的線程函數(shù) threadfn() 調(diào)用了 do_exit() 函數(shù),最好就不要再調(diào)用 kthread_stop() 函數(shù)了。

kthread_stop() 函數(shù)等待線程退出是通過 wait_for_completion() 函數(shù)實現(xiàn)的,相關(guān)的C語言代碼如下,請看:

Linux和Windows兩種風格的操作系統(tǒng),創(chuàng)建線程的方式有何不同?

wait_for_completion() 函數(shù)

稍稍跟蹤一下C語言代碼,發(fā)現(xiàn)其實這一等待過程是由 do_wait_for_common()函數(shù)實現(xiàn)的,它的C語言代碼如下,請看:

Linux和Windows兩種風格的操作系統(tǒng),創(chuàng)建線程的方式有何不同?

do_wait_for_common()函數(shù)

還是比較清晰的,這里就不再贅述了。至此,我們就了解了Linux內(nèi)核是如何創(chuàng)建線程并投入運行,以及如何結(jié)束內(nèi)核線程的了。

小結(jié)

本節(jié)主要討論了 Linux 內(nèi)核中的線程的創(chuàng)建,應(yīng)該能夠看出,其實核心還是圍繞對 task_struct 結(jié)構(gòu)的管理,這與管理進程并無過多區(qū)別。因此,說Linux中的線程只是一種特殊的進程,一點也不為過。

歡迎在評論區(qū)一起討論,質(zhì)疑。文章都是手打原創(chuàng),每天最淺顯的介紹C語言、linux等嵌入式開發(fā),喜歡我的文章就關(guān)注一波吧,可以看到最新更新和之前的文章哦(最近發(fā)現(xiàn)有些帳號搬運我的文章并且標上原創(chuàng)標簽,有些可恥,請注明出處?。。?。

分享到:
標簽:操作系統(tǒng)
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定