1. 在Linux下實(shí)現(xiàn)進(jìn)度條程序。 通過makefile進(jìn)行編譯。 建議自主完成一個(gè)彩色的進(jìn)度條。
寫Makefile文件的原因:Makefile文件的作用是命令行編譯鏈接命令nmake使用的文件。它以人本方式規(guī)定了make要編譯哪些文件,生成哪些文件,要鏈接哪些文件,生成的.exe文件的名稱等。
思路:
1. 進(jìn)度條由0%-100%,在字符數(shù)組中輸出一串字符時(shí),最后以”\0”結(jié)束的,所以需要一個(gè)大小為102的數(shù)組,加載橙紅的數(shù)據(jù)用”=”表示。
2. 進(jìn)度條會(huì)出現(xiàn)一個(gè)區(qū)間,然后在里面進(jìn)行加載,故先用”[“”]”表示加載的區(qū)間。
3. 定義一個(gè)rate標(biāo)識(shí)進(jìn)度。沒進(jìn)行一次加一,直到100停止
4. 在進(jìn)行回車前,需要進(jìn)行刷新
5. 在加載進(jìn)度時(shí),通過sleep()&usleep()控制睡眠時(shí)間,sleep表示秒,usleep表示微妙。
6. 對(duì)于加載中旋轉(zhuǎn)的小圈通過”-|/”順時(shí)針進(jìn)行。
主要代碼如下
#include #include int main() { int rate =0; char str[102]={0}; char * sta=“-\|/”; while(rate《=100) { str[rate]=“-”; printf(“[%-100s],%d%%,[%c]\r”,str,rate,sta[rate%4]); rate++; ffush(stdout); usleep(100000); } retunr 0; }
Linux下程序編寫完成之后,在進(jìn)行編譯鏈接生成可執(zhí)行文件
方式1 gcc test.c -o test
。/a.out
方式2 編譯makefile文件
test:test。o gcc -o test -o test.o test.o:test.s gcc -C test.i -o test.o test.s:test.i gcc -S test.i -p test.i test.i:test.c gcc -E test.c -o test.i .PHONY:clean clean: rm -f test.o rm -f test.s rm -f test.i rm -f test 1.回車(\r)和換行(\n)
回車和換行是兩個(gè)不同的概念,回車:表示回到當(dāng)前行的行首。換行:表示光標(biāo)進(jìn)入當(dāng)前行的下一行
在Linux中,\n會(huì)進(jìn)行回車+換行操作,而/r不會(huì)進(jìn)行回車操作,只會(huì)被當(dāng)做控制字符處理。
在Windows下,每行的結(jié)尾是《\n》《\r》;在Linux下,每行的結(jié)尾是《\n》。所以,Linux下打開Windows的文件,每行會(huì)多出一個(gè)^M符號(hào);而在Windows下打開Linux文件,所有的內(nèi)容變成一行。
2.緩沖區(qū)
####(1)什么是緩沖區(qū)?
緩沖區(qū)又稱為緩存,它是內(nèi)存空間的一部分,在內(nèi)存空間中預(yù)留了一定的存儲(chǔ)空間,這些空間用來緩沖輸入或輸出的書庫(kù),這部分預(yù)留的空間就叫做緩沖區(qū)。
緩沖區(qū)根據(jù)其對(duì)應(yīng)的是輸入涉筆還是輸出設(shè)備,分為輸入緩沖區(qū)和輸出緩沖區(qū)。
(2)為什么要引入緩沖區(qū)
比如我們從磁盤里取信息,我們先把讀出的數(shù)據(jù)放在緩沖區(qū),計(jì)算機(jī)再直接從緩沖區(qū)中取數(shù)據(jù),等緩沖區(qū)的數(shù)據(jù)取完后再去磁盤中讀取,這樣就可以減少磁盤的讀寫次數(shù),再加上計(jì)算機(jī)對(duì)緩沖區(qū)的操作大大快于對(duì)磁盤的操作,故應(yīng)用緩沖區(qū)可大大提高計(jì)算機(jī)的運(yùn)行速度。
又比如,我們使用打印機(jī)打印文檔,由于打印機(jī)的打印速度相對(duì)較慢,我們先把文檔輸出到打印機(jī)相應(yīng)的緩沖區(qū),打印機(jī)再自行逐步打印,這時(shí)我們的CPU可以處理別的事情。
現(xiàn)在您基本明白了吧,緩沖區(qū)就是一塊內(nèi)存區(qū),它用在輸入輸出設(shè)備和CPU之間,用來緩存數(shù)據(jù)。它使得低速的輸入輸出設(shè)備和高速的CPU能夠協(xié)調(diào)工作,避免低速的輸入輸出設(shè)備占用CPU,解放出CPU,使其能夠高效率工作。
(3)緩沖區(qū)的類型
緩沖區(qū) 分為三種類型:全緩沖、行緩沖和不帶緩沖。
a、全緩沖
在這種情況下,當(dāng)填滿標(biāo)準(zhǔn)I/O緩存后才進(jìn)行實(shí)際I/O操作。全緩沖的典型代表是對(duì)磁盤文件的讀寫。
b、行緩沖
在這種情況下,當(dāng)在輸入和輸出中遇到換行符時(shí),執(zhí)行真正的I/O操作。這時(shí),我們輸入的字符先存放在緩沖區(qū),等按下回車鍵換行時(shí)才進(jìn)行實(shí)際的I/O操作。典型代表是鍵盤輸入數(shù)據(jù)。
c、不帶緩沖
也就是不進(jìn)行緩沖,標(biāo)準(zhǔn)出錯(cuò)情況stderr是典型代表,這使得出錯(cuò)信息可以直接盡快地顯示出來。
(4)緩沖區(qū)的刷新 下列情況會(huì)引發(fā)緩沖區(qū)的刷新: 1、緩沖區(qū)滿時(shí); 2、執(zhí)行flush語句; 3、執(zhí)行endl語句; 4、關(guān)閉文件。 可見,緩沖區(qū)滿或關(guān)閉文件時(shí)都會(huì)刷新緩沖區(qū),進(jìn)行真正的I/O操作。另外,在C++中,我們可以使用flush函數(shù)來刷新緩沖區(qū)(執(zhí)行I/O操作并清空緩沖區(qū)),如:cout《Linux下呢,有一個(gè)萬能的“男人”,我們有什么不懂得,就可以去問這個(gè)“男人”,它就是man指令。下面我們以查詢fflush()函數(shù)的頭文件來使用man命令查詢,輸入man fflush后按回車鍵,就會(huì)出現(xiàn)一個(gè)查詢文檔。
2.Linux下軟件安裝的幾種方式
rpm安裝的常用選項(xiàng)
操作符 作用
rpm -ivh full_pkgname 安裝
rpm -e pkgame 卸載
rpm -qa[pkgame] 列出所有已經(jīng)安裝過的包
rpm -ql pkgame 列出一個(gè)已經(jīng)安裝的包安裝了哪些文件
rpm -qf file 列出某個(gè)文件由哪幾個(gè)包安裝
rpm -qi file 查詢某個(gè)安裝包的詳細(xì)信息
rpm -nodeps 強(qiáng)制安裝,不用管其他依賴的包
rpm -force 強(qiáng)制安裝,而不管系統(tǒng)中有沒有安裝過這個(gè)包
yum安裝
- yum工具是RedHat公司開發(fā)的用于管理rpm包的工具
- 使用yum安裝rpm包可以自動(dòng)解決包之間的依賴關(guān)系
- 我們可以自定義yum的源,可以搭建本地yum倉(cāng)庫(kù)
- yum源配置文件為/etc/yum.repos.d/CentOS-Base.repo
操作符 作用
yum install pkg 安裝rpm包
yum remove pkg 卸載rpm包
yum list 從配置文件中指定的yum源列出所有的rpm安裝包
yum search xxx 搜索rpm包
yum groupinstall grp 安裝rpm組件
yum groupremove grp 卸載rpm組件
yum grouplist 列出所有的rpm組件
yum update/yum upgrade 更新所有的rpm包
搭建本地yum庫(kù)
1. 將centos安裝盤或安裝鏡像掛載到指定路徑mnt/
2. 備份好配置文件 /etc/yum.repos.d/CentOS-Base.repo到一個(gè)指定路徑
3. 刪除配置文件 /etc/yum.repos.d/CentOS-Base.repo
4. 編輯另一個(gè)配置文件 /etc/yum.repos.d/CentOS-Media.repo
[local-cdrom] —-》 yum list 時(shí)顯示在最右邊的標(biāo)識(shí);
name=cd —-》 yum 倉(cāng)庫(kù)標(biāo)識(shí);
baseurl=file:///mnt/ —-》 指定 rpm 倉(cāng)庫(kù)路徑;
gpgcheck=0 —-》 不檢測(cè);
enabled=1 —-》 允許 ;
5. 保存退出
使用yum只下載不安裝rpm包
1. 先安裝一個(gè)插件:yum install -y yum-plugin-downloadonly;
2. 對(duì)于未安裝過的 rpm 包:yum install -y pkg –downloadonly;
3. 對(duì)于已經(jīng)安裝過的:yum reinstall -y pkg –downloadonly;
4. 指定 rpm 包的下載路徑:yum install -y pkg –downloadonly –downloaddir dir.
源碼安裝
1. 下載源碼包盡量從官網(wǎng)下載,保證安全
2. 源碼包保存路徑約定為:/usr/local/src/
3. 安裝路徑約定為:/usr/local/源碼包名
4. 安裝開始前,先要查看安裝說明 vim INSTALL vim README
5. 查看配置參數(shù):。/configure –help
6. 安裝過程中,每進(jìn)行完一步要使用echo $? 進(jìn)行驗(yàn)證前一步是否產(chǎn)生錯(cuò)誤
操作符 作用
。/configure –help 查看所有配置參數(shù)及含義
。/configure … 配置安裝路徑、安裝模塊
make 編譯
make install 安裝
echo $! 檢查上一步安裝是否出錯(cuò),‘0’:正確;‘1’:錯(cuò)誤
調(diào)研task_struct結(jié)構(gòu)體, 理解結(jié)構(gòu)體中的各個(gè)字段的含義
Linux內(nèi)核通過一個(gè)被稱為進(jìn)程描述符的task_struct結(jié)構(gòu)體來管理進(jìn)程,
task_struct是Linux中的【進(jìn)程控制塊PCB結(jié)構(gòu)】的具體數(shù)據(jù)結(jié)構(gòu)
這個(gè)結(jié)構(gòu)體包含了一個(gè)進(jìn)程所需的所有信息。它定義在linux-2.6.38.8/include/linux/sched.h文件中。
下面對(duì)task_struct這個(gè)結(jié)構(gòu)體 進(jìn)行各個(gè)字段的詳細(xì)介紹
1. 調(diào)度數(shù)據(jù)成員 (1) volatile long states;
表示進(jìn)程的當(dāng)前狀態(tài):
- TASK_RUNNING:正在運(yùn)行或在就緒隊(duì)列run-queue中準(zhǔn)備運(yùn)行的進(jìn)程,實(shí)際參與進(jìn)程調(diào)度。
- TASK_INTERRUPTIBLE:處于等待隊(duì)列中的進(jìn)程,待資源有效時(shí)喚醒,也可由其它進(jìn)程通過信號(hào)(signal)或定時(shí)中斷喚醒后進(jìn)入就緒隊(duì)列run-queue。
- TASK_UNINTERRUPTIBLE:處于等待隊(duì)列中的進(jìn)程,待資源有效時(shí)喚醒,不可由其它進(jìn)程通過信號(hào)(signal)或定時(shí)中斷喚醒。
- TASK_ZOMBIE:表示進(jìn)程結(jié)束但尚未消亡的一種狀態(tài)(僵死狀態(tài))。此時(shí),進(jìn)程已經(jīng)結(jié)束運(yùn)行且釋放大部分資源,但尚未釋放進(jìn)程控制塊。
- TASK_STOPPED:進(jìn)程被暫停,通過其它進(jìn)程的信號(hào)才能喚醒。導(dǎo)致這種狀態(tài)的原因有二,或者是對(duì)收到SIGSTOP、SIGSTP、SIGTTIN或SIGTTOU信號(hào)的反應(yīng),或者是受其它進(jìn)程的ptrace系統(tǒng)調(diào)用的控制而暫時(shí)將CPU交給控制進(jìn)程。
- TASK_SWAPPING: 進(jìn)程頁(yè)面被交換出內(nèi)存的進(jìn)程。
(2) unsigned long flags;
進(jìn)程標(biāo)志:
- PF_ALIGNWARN 打印“對(duì)齊”警告信息。
- PF_PTRACED 被ptrace系統(tǒng)調(diào)用監(jiān)控。
- PF_TRACESYS 正在跟蹤。
- PF_FORKNOEXEC 進(jìn)程剛創(chuàng)建,但還沒執(zhí)行。
- PF_SUPERPRIV 超級(jí)用戶特權(quán)。
- PF_DUMPCORE dumped core。
- PF_SIGNALED 進(jìn)程被信號(hào)(signal)殺出。
- PF_STARTING 進(jìn)程正被創(chuàng)建。
- PF_EXITING 進(jìn)程開始關(guān)閉。
- PF_USEDFPU 該進(jìn)程使用FPU(SMP only)。
- PF_DTRACE delayed trace (used on m68k)。
(3) long priority;
進(jìn)程優(yōu)先級(jí)。 Priority的值給出進(jìn)程每次獲取CPU后可使用的時(shí)間(按jiffies計(jì))。優(yōu)先級(jí)可通過系統(tǒng)調(diào)用sys_setpriorty改變(在kernel/sys.c中)。
(4) unsigned long rt_priority;
rt_priority給出實(shí)時(shí)進(jìn)程的優(yōu)先級(jí),rt_priority+1000給出進(jìn)程每次獲取CPU后可使用的時(shí)間(同樣按jiffies計(jì))。實(shí)時(shí)進(jìn)程的優(yōu)先級(jí)可通過系統(tǒng)調(diào)用sys_sched_setscheduler()改變(見kernel/sched.c)。
(5) long counter;
在輪轉(zhuǎn)法調(diào)度時(shí)表示進(jìn)程當(dāng)前還可運(yùn)行多久。在進(jìn)程開始運(yùn)行是被賦為priority的值,以后每隔一個(gè)tick(時(shí)鐘中斷)遞減1,減到0時(shí)引起新一輪調(diào)度。重新調(diào)度將從run_queue隊(duì)列選出counter值最大的就緒進(jìn)程并給予CPU使用權(quán),因此counter起到了進(jìn)程的動(dòng)態(tài)優(yōu)先級(jí)的作用(priority則是靜態(tài)優(yōu)先級(jí))。
(6) unsigned long policy;
該進(jìn)程的進(jìn)程調(diào)度策略,可以通過系統(tǒng)調(diào)用sys_sched_setscheduler()更改(見kernel/sched.c)。調(diào)度策略有:
- SCHED_OTHER 0 非實(shí)時(shí)進(jìn)程,基于優(yōu)先權(quán)的輪轉(zhuǎn)法(round robin)。
- SCHED_FIFO 1 實(shí)時(shí)進(jìn)程,用先進(jìn)先出算法。
- SCHED_RR 2 實(shí)時(shí)進(jìn)程,用基于優(yōu)先權(quán)的輪轉(zhuǎn)法。
2. 信號(hào)處理 (1) unsigned long signal;
進(jìn)程接收到的信號(hào)。每位表示一種信號(hào),共32種。置位有效。
(2) unsigned long blocked;
進(jìn)程所能接受信號(hào)的位掩碼。置位表示屏蔽,復(fù)位表示不屏蔽。
(3) struct signal_struct *sig;
因?yàn)閟ignal和blocked都是32位的變量,Linux最多只能接受32種信號(hào)。對(duì)每種信號(hào),各進(jìn)程可以由PCB的sig屬性選擇使用自定義的處理函數(shù),或是系統(tǒng)的缺省處理函數(shù)。指派各種信息處理函數(shù)的結(jié)構(gòu)定義在include/linux/sched.h中。對(duì)信號(hào)的檢查安排在系統(tǒng)調(diào)用結(jié)束后,以及“慢速型”中斷服務(wù)程序結(jié)束后(IRQ#_interrupt(),參見Array。5節(jié)“啟動(dòng)內(nèi)核”)。
3. 進(jìn)程隊(duì)列指針 (1) struct task_struct *next_task,*prev_task;
所有進(jìn)程(以PCB的形式)組成一個(gè)雙向鏈表。next_task和就是鏈表的前后指針。鏈表的頭和尾都是init_task(即0號(hào)進(jìn)程)。
(2) struct task_struct *next_run,*prev_run;
由正在運(yùn)行或是可以運(yùn)行的,其進(jìn)程狀態(tài)均為TASK_RUNNING的進(jìn)程所組成的一個(gè)雙向循環(huán)鏈表,即run_queue就緒隊(duì)列。該鏈表的前后向指針用next_run和prev_run,鏈表的頭和尾都是init_task(即0號(hào)進(jìn)程)。
(3) struct task_struct *p_opptr,*p_pptr;和struct task_struct *p_cptr,*p_ysptr,*p_osptr; 以上分別是指向原始父進(jìn)程(original parent)、父進(jìn)程(parent)、子進(jìn)程(youngest child)及新老兄弟進(jìn)程(younger sibling,older sibling)的指針。 4. 進(jìn)程標(biāo)識(shí) (1) unsigned short uid,gid;
uid和gid是運(yùn)行進(jìn)程的用戶標(biāo)識(shí)和用戶組標(biāo)識(shí)。
(2) int groups[NGROUPS];
與多數(shù)現(xiàn)代UNIX操作系統(tǒng)一樣,Linux允許進(jìn)程同時(shí)擁有一組用戶組號(hào)。在進(jìn)程訪問文件時(shí),這些組號(hào)可用于合法性檢查。
(3) unsigned short euid,egid;
euid和egid又稱為有效的uid和gid。出于系統(tǒng)安全的權(quán)限的考慮,運(yùn)行程序時(shí)要檢查euid和egid的合法性。通常,uid等于euid,gid等于egid。有時(shí)候,系統(tǒng)會(huì)賦予一般用戶暫時(shí)擁有root的uid和gid(作為用戶進(jìn)程的euid和egid),以便于進(jìn)行運(yùn)作。
(4) unsigned short fsuid,fsgid;
fsuid和fsgid稱為文件系統(tǒng)的uid和gid,用于文件系統(tǒng)操作時(shí)的合法性檢查,是Linux獨(dú)特的標(biāo)識(shí)類型。它們一般分別和euid和egid一致,但在NFS文件系統(tǒng)中NFS服務(wù)器需要作為一個(gè)特殊的進(jìn)程訪問文件,這時(shí)只修改客戶進(jìn)程的fsuid和fsgid。
(5) unsigned short suid,sgid;
suid和sgid是根據(jù)POSIX標(biāo)準(zhǔn)引入的,在系統(tǒng)調(diào)用改變uid和gid時(shí),用于保留真正的uid和gid。
(6) int pid,pgrp,session;
進(jìn)程標(biāo)識(shí)號(hào)、進(jìn)程的組織號(hào)及session標(biāo)識(shí)號(hào),相關(guān)系統(tǒng)調(diào)用(見程序kernel/sys.c)有sys_setpgid、sys_getpgid、sys_setpgrp、sys_getpgrp、sys_getsid及sys_setsid幾種。
(7) int leader;
是否是session的主管,布爾量。
5. 時(shí)間數(shù)據(jù)成員 (1) unsigned long timeout;
用于軟件定時(shí),指出進(jìn)程間隔多久被重新喚醒。采用tick為單位。
(2) unsigned long it_real_value,it_real_iner;
用于itimer(interval timer)軟件定時(shí)。采用jiffies為單位,每個(gè)tick使it_real_value減到0時(shí)向進(jìn)程發(fā)信號(hào)SIGALRM,并重新置初值。初值由it_real_incr保存。具體代碼見kernel/itimer.c中的函數(shù)it_real_fn()。
(3) struct timer_list real_timer;
一種定時(shí)器結(jié)構(gòu)(Linux共有兩種定時(shí)器結(jié)構(gòu),另一種稱作old_timer)。數(shù)據(jù)結(jié)構(gòu)的定義在include/linux/timer.h中,相關(guān)操作函數(shù)見kernel/sched.c中add_timer()和del_timer()等。
(4) unsigned long it_virt_value,it_virt_incr;
關(guān)于進(jìn)程用戶態(tài)執(zhí)行時(shí)間的itimer軟件定時(shí)。采用jiffies為單位。進(jìn)程在用戶態(tài)運(yùn)行時(shí),每個(gè)tick使it_virt_value減1,減到0時(shí)向進(jìn)程發(fā)信號(hào)SIGVTALRM,并重新置初值。初值由it_virt_incr保存。具體代碼見kernel/sched.c中的函數(shù)do_it_virt()。
(5) unsigned long it_prof_value,it_prof_incr;
同樣是itimer軟件定時(shí)。采用jiffies為單位。不管進(jìn)程在用戶態(tài)或內(nèi)核態(tài)運(yùn)行,每個(gè)tick使it_prof_value減1,減到0時(shí)向進(jìn)程發(fā)信號(hào)SIGPROF,并重新置初值。初值由it_prof_incr保存。 具體代碼見kernel/sched.c中的函數(shù)do_it_prof。
(6) long utime,stime,cutime,cstime,start_time;
以上分別為進(jìn)程在用戶態(tài)的運(yùn)行時(shí)間、進(jìn)程在內(nèi)核態(tài)的運(yùn)行時(shí)間、所有層次子進(jìn)程在用戶態(tài)的運(yùn)行時(shí)間總和、所有層次子進(jìn)程在核心態(tài)的運(yùn)行時(shí)間總和,以及創(chuàng)建該進(jìn)程的時(shí)間。
6. 信號(hào)量數(shù)據(jù)成員 (1) struct sem_undo *semundo;
進(jìn)程每操作一次信號(hào)量,都生成一個(gè)對(duì)此次操作的undo操作,它由sem_undo結(jié)構(gòu)描述。這些屬于同一進(jìn)程的undo操作組成的鏈表就由semundo屬性指示。當(dāng)進(jìn)程異常終止時(shí),系統(tǒng)會(huì)調(diào)用undo操作。sem_undo的成員semadj指向一個(gè)數(shù)據(jù)數(shù)組,表示各次undo的量。結(jié)構(gòu)定義在include/linux/sem.h。
(2) struct sem_queue *semsleeping;
每一信號(hào)量集合對(duì)應(yīng)一個(gè)sem_queue等待隊(duì)列(見include/linux/sem.h)。進(jìn)程因操作該信號(hào)量集合而阻塞時(shí),它被掛到semsleeping指示的關(guān)于該信號(hào)量集合的sem_queue隊(duì)列。反過來,semsleeping。sleeper指向該進(jìn)程的PCB。
7. 進(jìn)程上下文環(huán)境 (1) struct desc_struct *ldt;
進(jìn)程關(guān)于CPU段式存儲(chǔ)管理的局部描述符表的指針,用于仿真WINE Windows的程序。其他情況下取值NULL,進(jìn)程的ldt就是arch/i386/traps.c定義的default_ldt。
(2) struct thread_struct tss;
任務(wù)狀態(tài)段,其內(nèi)容與INTEL CPU的TSS對(duì)應(yīng),如各種通用寄存器.CPU調(diào)度時(shí),當(dāng)前運(yùn)行進(jìn)程的TSS保存到PCB的tss,新選中進(jìn)程的tss內(nèi)容復(fù)制到CPU的TSS。結(jié)構(gòu)定義在include/linux/tasks.h中。
(3) unsigned long saved_kernel_stack;
為MS-DOS的仿真程序(或叫系統(tǒng)調(diào)用vm86)保存的堆棧指針。
(4) unsigned long kernel_stack_page;
在內(nèi)核態(tài)運(yùn)行時(shí),每個(gè)進(jìn)程都有一個(gè)內(nèi)核堆棧,其基地址就保存在kernel_stack_page中。
8. 文件系統(tǒng)數(shù)據(jù)成員 (1) struct fs_struct *fs;
fs保存了進(jìn)程本身與VFS的關(guān)系消息,其中root指向根目錄結(jié)點(diǎn),pwd指向當(dāng)前目錄結(jié)點(diǎn),umask給出新建文件的訪問模式(可由系統(tǒng)調(diào)用umask更改),count是Linux保留的屬性,如下頁(yè)圖所示。結(jié)構(gòu)定義在include/linux/sched.h中。
(2) struct files_struct *files;
files包含了進(jìn)程當(dāng)前所打開的文件(struct file *fd[NR_OPEN])。在Linux中,一個(gè)進(jìn)程最多只能同時(shí)打開NR_OPEN個(gè)文件。而且,前三項(xiàng)分別預(yù)先設(shè)置為標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和出錯(cuò)消息輸出文件。
(3) int link_count;文件鏈(link)的數(shù)目。
Array. 內(nèi)存數(shù)據(jù)成員
(4) struct mm_struct *mm;
在linux中,采用按需分頁(yè)的策略解決進(jìn)程的內(nèi)存需求。task_struct的數(shù)據(jù)成員mm指向關(guān)于存儲(chǔ)管理的mm_struct結(jié)構(gòu)。其中包含了一個(gè)虛存隊(duì)列mmap,指向由若干vm_area_struct描述的虛存塊。同時(shí),為了加快訪問速度,mm中的mmap_avl維護(hù)了一個(gè)AVL樹。在樹中,所有的vm_area_struct虛存塊均由左指針指向相鄰的低虛存塊,右指針指向相鄰的高虛存塊。 結(jié)構(gòu)定義在include/linux/sched.h中。
10. 頁(yè)面管理 (1) int swappable:1;
進(jìn)程占用的內(nèi)存頁(yè)面是否可換出。swappable為1表示可換出。對(duì)該標(biāo)志的復(fù)位和置位均在do_fork()函數(shù)中執(zhí)行(見kerenl/fork.c)。
(2) unsigned long swap_address;
虛存地址比swap_address低的進(jìn)程頁(yè)面,以前已經(jīng)換出或已換出過,進(jìn)程下一次可換出的頁(yè)面自swap_address開始。參見swap_out_process()和swap_out_pmd()(見mm/vmscan.c)。
(3) unsigned long min_flt,maj_flt;
該進(jìn)程累計(jì)的minor缺頁(yè)次數(shù)和major缺頁(yè)次數(shù)。maj_flt基本與min_flt相同,但計(jì)數(shù)的范圍比后者廣(參見fs/buffer.c和mm/page_alloc.c)。min_flt只在do_no_page()、do_wp_page()里(見mm/memory.c)計(jì)數(shù)新增的可以寫操作的頁(yè)面。
(4) unsigned long nswap;
該進(jìn)程累計(jì)換出的頁(yè)面數(shù)。
(5) unsigned long cmin_flt,cmaj_flt,cnswap;
以本進(jìn)程作為祖先的所有層次子進(jìn)程的累計(jì)換入頁(yè)面、換出頁(yè)面計(jì)數(shù)。
(6) unsigned long old_maj_flt,dec_flt; (7) unsigned long swap_cnt;
下一次信號(hào)最多可換出的頁(yè)數(shù)。
11. 支持對(duì)稱多處理器方式(SMP)時(shí)的數(shù)據(jù)成員 (1) int processor;
進(jìn)程正在使用的CPU。
(2) int last_processor;
進(jìn)程最后一次使用的CPU。
(3) int lock_depth;
上下文切換時(shí)系統(tǒng)內(nèi)核鎖的深度。
12. 其它數(shù)據(jù)成員 (1) unsigned short used_math;
是否使用FPU。
(2) char comm[16];
進(jìn)程正在運(yùn)行的可執(zhí)行文件的文件名。
(3) struct rlimit rlim[RLIM_NLIMITS];
結(jié)構(gòu)rlimit用于資源管理,定義在linux/include/linux/resource.h中,成員共有兩項(xiàng):rlim_cur是資源的當(dāng)前最大數(shù)目;rlim_max是資源可有的最大數(shù)目。在i386環(huán)境中,受控資源共有RLIM_NLIMITS項(xiàng),即10項(xiàng),定義在linux/include/asm/resource.h中,見下表:
(4) int errno;
最后一次出錯(cuò)的系統(tǒng)調(diào)用的錯(cuò)誤號(hào),0表示無錯(cuò)誤。系統(tǒng)調(diào)用返回時(shí),全程量也擁有該錯(cuò)誤號(hào)。
(5) long debugreg[8];
保存INTEL CPU調(diào)試寄存器的值,在ptrace系統(tǒng)調(diào)用中使用。
(6) struct exec_domain *exec_domain;
Linux可以運(yùn)行由80386平臺(tái)其它UNIX操作系統(tǒng)生成的符合iBCS2標(biāo)準(zhǔn)的程序。關(guān)于此類程序與Linux程序差異的消息就由exec_domain結(jié)構(gòu)保存。
(7) unsigned long personality;
Linux可以運(yùn)行由80386平臺(tái)其它UNIX操作系統(tǒng)生成的符合iBCS2標(biāo)準(zhǔn)的程序。 Personality進(jìn)一步描述進(jìn)程執(zhí)行的程序?qū)儆诤畏NUNIX平臺(tái)的“個(gè)性”信息。通常有PER_Linux、PER_Linux_32BIT、PER_Linux_EM86、PER_SVR3、PER_SCOSVR3、PER_WYSEV386、PER_ISCR4、PER_BSD、PER_XENIX和PER_MASK等,參見include/linux/personality.h。
(8) struct linux_binfmt *binfmt;
指向進(jìn)程所屬的全局執(zhí)行文件格式結(jié)構(gòu),共有a。out、script、elf和java等四種。結(jié)構(gòu)定義在include/linux/binfmts.h中(core_dump、load_shlib(fd)、load_binary、use_count)。
(Array) int exit_code,exit_signal;
引起進(jìn)程退出的返回代碼exit_code,引起錯(cuò)誤的信號(hào)名exit_signal。
(9) int dumpable:1;
布爾量,表示出錯(cuò)時(shí)是否可以進(jìn)行memory dump。
(10) int did_exec:1;
按POSIX要求設(shè)計(jì)的布爾量,區(qū)分進(jìn)程是正在執(zhí)行老程序代碼,還是在執(zhí)行execve裝入的新代碼。
(11) int tty_old_pgrp;
進(jìn)程顯示終端所在的組標(biāo)識(shí)。
(12) struct tty_struct *tty;
指向進(jìn)程所在的顯示終端的信息。如果進(jìn)程不需要顯示終端,如0號(hào)進(jìn)程,則該指針為空。結(jié)構(gòu)定義在include/linux/tty.h中。
(13) struct wait_queue *wait_chldexit;
在進(jìn)程結(jié)束時(shí),或發(fā)出系統(tǒng)調(diào)用wait4后,為了等待子進(jìn)程的結(jié)束,而將自己(父進(jìn)程)睡眠在該隊(duì)列上。結(jié)構(gòu)定義在include/linux/wait.h中。
13. 進(jìn)程隊(duì)列的全局變量 (1) current;
當(dāng)前正在運(yùn)行的進(jìn)程的指針,在SMP中則指向CPU組中正被調(diào)度的CPU的當(dāng)前進(jìn)程:
#define current(0+current_set[smp_processor_id()])/sched.h/
struct task_struct *current_set[NR_CPUS];
(2) struct task_struct init_task;
即0號(hào)進(jìn)程的PCB,是進(jìn)程的“根”,始終保持初值INIT_TASK。
(3) struct task_struct *task[NR_TASKS];
進(jìn)程隊(duì)列數(shù)組,規(guī)定系統(tǒng)可同時(shí)運(yùn)行的最大進(jìn)程數(shù)(見kernel/sched.c)。NR_TASKS定義在include/linux/tasks.h中,值為512。每個(gè)進(jìn)程占一個(gè)數(shù)組元素(元素的下標(biāo)不一定就是進(jìn)程的pid),task[0]必須指向init_task(0號(hào)進(jìn)程)。可以通過task[]數(shù)組遍歷所有進(jìn)程的PCB。但Linux也提供一個(gè)宏定義for_each_task()(見include/linux/sched.h),它通過next_task遍歷所有進(jìn)程的PCB:
#define for_each_task(p) \
for(p=&init_task;(p=p-》next_task)!=&init_task;)
(4) unsigned long volatile jiffies;
Linux的基準(zhǔn)時(shí)間(見kernal/sched.c)。系統(tǒng)初始化時(shí)清0,以后每隔10ms由時(shí)鐘中斷服務(wù)程序do_timer()增1。
(5) int need_resched;
重新調(diào)度標(biāo)志位(見kernal/sched.c)。當(dāng)需要Linux調(diào)度時(shí)置位。在系統(tǒng)調(diào)用返回前(或者其它情形下),判斷該標(biāo)志是否置位。置位的話,馬上調(diào)用schedule進(jìn)行CPU調(diào)度。
(6) unsigned long intr_count;
記錄中斷服務(wù)程序的嵌套層數(shù)(見kernal/softirq.c)。正常運(yùn)行時(shí),intr_count為0。當(dāng)處理硬件中斷、執(zhí)行任務(wù)隊(duì)列中的任務(wù)或者執(zhí)行bottom half隊(duì)列中的任務(wù)時(shí),intr_count非0。這時(shí),內(nèi)核禁止某些操作,例如不允許重新調(diào)度。
評(píng)論