日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

linux设备驱动归纳总结(四):1.进程管理的相关概念【转】

發(fā)布時間:2025/6/15 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux设备驱动归纳总结(四):1.进程管理的相关概念【转】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文轉(zhuǎn)載自;http://blog.chinaunix.net/uid-25014876-id-64866.html

linux設(shè)備驅(qū)動歸納總結(jié)(四):1.進(jìn)程管理的相關(guān)概念

?

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

接下來的幾節(jié)我會大概的講一下內(nèi)核進(jìn)程的一些概念,其實應(yīng)該在學(xué)習(xí)系統(tǒng)編程時候就應(yīng)該知道的。。我參照的書籍是《linux內(nèi)核設(shè)計與實現(xiàn)》(第三版)。我會盡可能地跳開內(nèi)核代碼,簡述一下原理。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

?

一、什么是進(jìn)程

?

簡單的說,進(jìn)程就是正在運行的程序,一個程序可以同時有多個進(jìn)程。學(xué)過C語言都知道,程序運行時并不是只有代碼,還包含其他的資源,如打開的文件,信號,全局變量等等。我在《操作系統(tǒng)原理》中看過一個很生動很深刻的例子:一個人對照著菜譜做菜。在這例子中,人就是內(nèi)核,菜譜就是程序,做菜的過程就是進(jìn)程,而菜、鍋就是這個進(jìn)程的資源。

內(nèi)核為線程提供了兩種技術(shù):虛擬處理器和虛擬內(nèi)存。這就是說,每個進(jìn)程都傻乎乎的認(rèn)為自己獨占著CPU和享用這4G的內(nèi)存,確不知道內(nèi)核在背后調(diào)度進(jìn)程和給每個進(jìn)程4G的虛擬地址。

進(jìn)程由fork創(chuàng)建,通過exit退出。

有人或許會問,那線程是什么?線程就是一種特殊的進(jìn)程。

?

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

?

二、進(jìn)程是用什么結(jié)構(gòu)體來維護(hù)

?

內(nèi)核將所有的進(jìn)程放在叫任務(wù)隊列(task list的雙向循環(huán)鏈表中,鏈表中的每個項都是類型為task_struct、稱為進(jìn)程描述符的結(jié)構(gòu)。每個進(jìn)程描述符包含著一個進(jìn)程的所有信息,驅(qū)動開發(fā)中我用得最頻繁的有兩個成員,pid(進(jìn)程標(biāo)識值)comm(當(dāng)前進(jìn)程的所執(zhí)行的程序文件名稱)。

來張形象點的圖:

獲得當(dāng)前正在進(jìn)行的進(jìn)程進(jìn)程描述符也很簡單,使用全局項current就可以獲得。

/*4th_mutex/4th_mutex_1/1st/test.c*/

113 P_DEBUG("[%s]:pid[%d]\n", current->comm, current->pid);

?

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

?

三、進(jìn)程的狀態(tài)

?

我只說5種,其中前兩種是之前在等待隊列的時候介紹過。

1TASK_RUNNING(運行):該狀態(tài)出現(xiàn)在進(jìn)程正在運行,或者已經(jīng)放在運行隊列中等待執(zhí)行(對應(yīng)操作系統(tǒng)原理上所說的就緒狀態(tài))。這里要注意的是等待執(zhí)行和休眠是兩碼事

2TASK_INTERRUPTIBLE(可中斷休眠):這就是休眠狀態(tài)中一種,之所以說可中斷,就是說除了可以被其他進(jìn)程從等待隊列喚醒以外,還可以接送到信號而喚醒,這是常用的休眠狀態(tài)。

3TASK_UNINTERRUPTIBLE(不可中斷休眠):這就是休眠狀態(tài)的另一種,只能從等待隊列被喚醒。因為它如此霸道,所以很少有人使用。

4TASK_ZOMBIE(僵死):這種情況出現(xiàn)在進(jìn)程結(jié)束后,但父進(jìn)程還有來回收該進(jìn)程的進(jìn)程描述符

5TASK_STOPPED(停止):一看就知道,進(jìn)程停止執(zhí)行。

?

來個圖來對照前四種狀態(tài)的轉(zhuǎn)換:

由上圖可以看到用戶空間的進(jìn)程有fork()系統(tǒng)調(diào)用產(chǎn)生,如果運行途中沒有任何阻塞,它會在最后調(diào)用do_exit將進(jìn)程的狀態(tài)轉(zhuǎn)為TASK_ZOMBIE。等待父進(jìn)程來收尸。接下來就要簡單地說一下進(jìn)程的創(chuàng)建和進(jìn)程的終結(jié)

?

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

?

四、進(jìn)程的創(chuàng)建

進(jìn)程的創(chuàng)建一般分兩步:

?

1、調(diào)用fork()

在系統(tǒng)編程時,我們一般都是調(diào)用fork()來創(chuàng)建新的用戶進(jìn)程。

先說一下傳統(tǒng)的forl()的實現(xiàn),傳統(tǒng)的fork()被調(diào)用后,內(nèi)核會拷貝父進(jìn)程的所有資源給新建的子進(jìn)程。要知道這是一個多愚蠢的操作,如果新建子進(jìn)程是打算執(zhí)行另一個新程序,之前的拷貝過程就白費了。

出于這樣的原因,linuxfork()有了寫時拷貝(copy-on-write)技術(shù)。從字面上就能理解意思,父進(jìn)程創(chuàng)建子進(jìn)程后,他給子進(jìn)程創(chuàng)建一個文件描述符,并且與子進(jìn)程以只讀方式共享原有的資源,只有在子進(jìn)程或者父進(jìn)程修改資源時,資源才會被復(fù)制。所以說,在不修改資源的情況下,fork()的實際開銷就兩樣:

1)復(fù)制父進(jìn)程的頁表給子進(jìn)程。大家應(yīng)該都知道,linux內(nèi)存管理使用的頁式管理,只要也就是說,只要把父進(jìn)程的頁表復(fù)制給子進(jìn)程,子進(jìn)程就能在頁表中找到與父進(jìn)程共享的4G虛擬地址了。

2)為子進(jìn)程創(chuàng)建唯一的進(jìn)程描述符。這個就不用解釋了,進(jìn)程與進(jìn)程描述符是一一對應(yīng)的。

?

fork具體調(diào)用的什么函數(shù)我就不詳細(xì)說了,不過應(yīng)該有這樣的一個概念:

fork->clone->do_fork()->copy_procrss

fork()系統(tǒng)調(diào)用根據(jù)提供的參數(shù)調(diào)用clone(),然后clone()去調(diào)用do_fork(),其中do_fork中完成了創(chuàng)建的大部分操作,里面有一個主要的函數(shù)copy_process()

?

2、調(diào)用exec()

一般的,創(chuàng)建的子進(jìn)程都不是為了完成父進(jìn)程中的任務(wù),而是需要執(zhí)行新的任務(wù)。exec()的作用就是讀取可執(zhí)行文件并加載到地址空間開始運行,可以類比成命令”./xxxxx”如果fork()后子進(jìn)程調(diào)用exec()執(zhí)行新的代碼,就不需要拷貝父進(jìn)程的資源了。所以,一般fork()之后都是子進(jìn)程先運行。

?

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

?

五、進(jìn)程的終結(jié):

?

一般的,進(jìn)程調(diào)用exit()結(jié)束進(jìn)程。相應(yīng)的,exit()是調(diào)用do_exit()進(jìn)行刪除進(jìn)程的資源和改變進(jìn)程狀態(tài)等操作。

?

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

?

六、什么是進(jìn)程上下文:

?

用戶態(tài)的應(yīng)用程序執(zhí)行系統(tǒng)調(diào)用時,它就會陷入內(nèi)核空間,此時,我們稱內(nèi)核“代表進(jìn)程執(zhí)行”并處于進(jìn)程上下文。簡單的說,以我們之前寫的驅(qū)動舉例,當(dāng)應(yīng)用成調(diào)用open,他就會陷入內(nèi)核調(diào)用驅(qū)動函數(shù)中的test_open,此時內(nèi)核就 處于進(jìn)程上下文了。

值得一提的是,在進(jìn)程上下文時,current始終有效,它還是指向應(yīng)用層中的進(jìn)程,所以在”1st”的例子中,tesp_open打印出來的進(jìn)程號current->pid與應(yīng)用層是一樣的。

?

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

?

七、線程、進(jìn)程和內(nèi)核線程程又是怎么樣的關(guān)系:

?

線程,它是進(jìn)程活動中的對象,最通俗的解釋,一個進(jìn)程里面可以有一個或者多個線程,它們共同享用進(jìn)程的資源。

內(nèi)核線程,獨立運行在內(nèi)核空間的標(biāo)準(zhǔn)進(jìn)程,但沒有獨立的運行空間,只運行在內(nèi)核空間,但和普通進(jìn)程一樣被調(diào)度和搶占。

總的來說,線程(又叫用戶線程)和內(nèi)核線程都是進(jìn)程的特殊形式,它們的創(chuàng)建同樣也是通過調(diào)用clone()它們和進(jìn)程的最大區(qū)別在于它們沒有獨立的4G虛擬空間

而線程和內(nèi)核線程的區(qū)別就是:線程存在與用戶態(tài),內(nèi)核線程存在與內(nèi)核態(tài)。

同時需要強(qiáng)調(diào)的是,進(jìn)程是存在于用戶態(tài)的。

?

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

?

八、總結(jié):

?

今天只是介紹了進(jìn)程的一些基本的概念,為以后的進(jìn)程調(diào)度、并發(fā)、競態(tài)等理論打基礎(chǔ)。

?

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

總結(jié)

以上是生活随笔為你收集整理的linux设备驱动归纳总结(四):1.进程管理的相关概念【转】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。