【正文】
es the current condition of the process. Each process on the system is in exactly one of five different states. This value is represented by one of five flags:(1) TASK_RUNNING The process is runnable。 it can also apply to a process in kernelspace that is actively running.(2) TASK_INTERRUPTIBLE. The process is sleeping (that is, it is blocked), waiting for some condition to exist. When this condition exists, the kernel sets the process39。s process descriptor must remain in case the parent wants to access it. If the parent calls wait4(), the process descriptor is deallocated.(5) TASK_STOPPED Process execution has stopped。s state. The preferred mechanism is using set_task_state(task, state)。 The method set_current_state(state) is synonymous to set_task_state(current, state).6 Process ContextOne of the most important parts of a process is the executing program code. This code is read in from an executable file and executed within the program39。一個(gè)進(jìn)程就是處于執(zhí)行期間的程序(目標(biāo)代碼放在某種存儲(chǔ)介質(zhì)上)。通常進(jìn)程還要包含其他資源,像打開的文件、掛起的信號(hào)、內(nèi)核內(nèi)部數(shù)據(jù)、處理器狀態(tài)、地址空間及一個(gè)或多個(gè)執(zhí)行線程、當(dāng)然還包括用來存放全局變量的數(shù)據(jù)段等。 執(zhí)行線程,簡(jiǎn)稱線程(thread),是在進(jìn)程中活動(dòng)的對(duì)象。內(nèi)核調(diào)度的對(duì)象是線程,而不是進(jìn)程。Linux系統(tǒng)的線程實(shí)現(xiàn)非常特別—他對(duì)線程和進(jìn)程并不特別區(qū)分。 在現(xiàn)代操作系統(tǒng)中,進(jìn)程提供兩種虛擬機(jī)制:虛擬處理器和虛擬內(nèi)存。而虛擬內(nèi)存讓進(jìn)程在獲取和使用內(nèi)存是覺得自己擁有整個(gè)操作系統(tǒng)的所有內(nèi)存資源。 程序本身并不是進(jìn)程:進(jìn)程是處于執(zhí)行期間的程序以及它所包含的資源的總稱。并且兩個(gè)或兩個(gè)以上并存的進(jìn)程還可以共享許多諸如打開的文件、地址空間之類的資源。在Linux系統(tǒng)中,這通常是調(diào)用fork()系統(tǒng)調(diào)用的結(jié)果,該系統(tǒng)調(diào)用通過復(fù)制一個(gè)現(xiàn)有進(jìn)程來創(chuàng)建一個(gè)全新的進(jìn)程。在調(diào)用結(jié)束的時(shí),在返回這個(gè)相同位置上,父進(jìn)程恢復(fù)執(zhí)行,子進(jìn)程開始執(zhí)行。 通常,創(chuàng)建新的進(jìn)程都是為了立即執(zhí)行新的、不同的程序,而接著調(diào)用exec()這族函數(shù)就可以創(chuàng)建新的地址空間,并把新的程序載入。 最終,程序通過exit()系統(tǒng)調(diào)用退出。父進(jìn)程可以通過wait()系統(tǒng)調(diào)用查詢子進(jìn)程是否終結(jié),這其實(shí)使得進(jìn)程擁有了等待指定進(jìn)程執(zhí)行完畢的能力。 進(jìn)程的另一個(gè)名字是任務(wù)(task)。在這里所說的任務(wù)是指從內(nèi)核觀點(diǎn)看到的進(jìn)程。鏈表的每一項(xiàng)都是類型為task_struct、稱為進(jìn)程描述符的結(jié)構(gòu),改結(jié)構(gòu)定義在linux/文件中。task_struct相對(duì)較大,在32位機(jī)器上。進(jìn)程描述符中包含的數(shù)據(jù)能完整的描述一個(gè)正在執(zhí)行的程序:它打開的文件,進(jìn)程的地址空間,掛起的信號(hào),進(jìn)程的狀態(tài),還有其他更多的信息。各個(gè)進(jìn)程的task_struct存放在他們的內(nèi)核棧的尾端。由于現(xiàn)在用slab分配器動(dòng)態(tài)生成task_struct,所以只需在棧底或棧頂創(chuàng)建一個(gè)新的結(jié)構(gòu)struct thread)info。在x86上,thread_info { Struct task_struct *任務(wù)。 Unsigned long flags。 __u32 cpu。 Mm_segment addr_limit。 Unsigned long previous_esp。}每個(gè)任務(wù)的thread_info 結(jié)構(gòu)在它的內(nèi)核棧的尾端分配。3 進(jìn)程描述符的存放內(nèi)核通過一個(gè)唯一的進(jìn)程標(biāo)識(shí)值或PID來表示每個(gè)進(jìn)程。為了老版本的Unix和Linux兼容,PID 的最大值默認(rèn)設(shè)置為32768,盡管這個(gè)值也可以增加到類型所允許的范圍。 這個(gè)值很重要,因?yàn)樗鼘?shí)際上就是系統(tǒng)中允許同時(shí)存在的進(jìn)程的最大數(shù)目。這個(gè)值越小,轉(zhuǎn)一圈就越快,本類數(shù)值大的進(jìn)程比數(shù)值小的進(jìn)程遲運(yùn)行,但這樣一來就破壞了這一原則。 在內(nèi)核中,訪問任務(wù)通常需要獲得指向其task_struct指針。因此,通過current宏查找到當(dāng)前正在運(yùn)行進(jìn)程的進(jìn)程描述符的速度就顯得尤為重要。有的硬件體系結(jié)構(gòu)可以拿出一個(gè)專門寄存器來存放指向當(dāng)前進(jìn)程task_strcut的指針,用于加快訪問速度。在x86體系上,current把棧指針的后13個(gè)有效位屏蔽掉,用來計(jì)算出thread_info的偏移。匯編代碼如下: Mov $81925, %eax Andl %esp, %eax 這里假定棧的大小為8KB。 最后,current_thread_info()task。也就是說,在PPC上,current宏只需要把r2寄存器中的值返回就行了。而訪問進(jìn)程描述符是一個(gè)重要的頻繁的操作,所以PPC的內(nèi)核開發(fā)者會(huì)覺得完全有必要為此使用一個(gè)專門的寄存器。系統(tǒng)的每個(gè)進(jìn)程都必然處于五種進(jìn)程狀態(tài)的一種。這是進(jìn)程在用戶空間中執(zhí)行唯一可能的狀態(tài),也可以應(yīng)用到內(nèi)核空間中正在執(zhí)行的進(jìn)程。一檔這些條件達(dá)成,內(nèi)核就會(huì)把進(jìn)程狀態(tài)設(shè)置為運(yùn)行。(3) TASK_UNINTERRUPTIBLE(不可中斷)——除了不會(huì)因?yàn)榻邮艿叫盘?hào)而被喚醒從而投入運(yùn)行外,這個(gè)狀態(tài)與可打斷的狀態(tài)相同。由于處于此狀態(tài)的任務(wù)對(duì)信號(hào)不做響應(yīng),所以較之可中斷狀態(tài),使用的較少。一旦父進(jìn)程調(diào)用了wait進(jìn)程描述符就會(huì)被釋放掉。通常這種狀態(tài)發(fā)生在接受到SIGSTOP、SIGTTIN、SIGTTOU等信號(hào)的時(shí)候。5 設(shè)置當(dāng)前進(jìn)程狀態(tài)內(nèi)核經(jīng)常需要調(diào)整某個(gè)進(jìn)程的狀態(tài)。 函數(shù)。必要的時(shí)候,它會(huì)設(shè)置內(nèi)存屏障來強(qiáng)制其他處理器作重新排序(一般只有在SMP系統(tǒng)中有此必要),否則,它等價(jià)于:Taskstate = state。6 進(jìn)程上下文可執(zhí)行程序代碼是進(jìn)程的重要組成部分。一般程序在用戶空間執(zhí)行。此時(shí),我們稱內(nèi)核“代表進(jìn)程執(zhí)行”并處于進(jìn)程上下文中。除非在此間隙有更高優(yōu)先級(jí)的進(jìn)程需要執(zhí)行并由調(diào)度器做出了相應(yīng)的調(diào)整,否則在內(nèi)核退出的時(shí)候,程序恢復(fù)在用戶空間繼續(xù)執(zhí)行。進(jìn)程只有通過這些接口才能陷入內(nèi)核執(zhí)行——對(duì)內(nèi)核的所有的訪問都必須通過這些