在linux中进程表示的是,Linux进程的表示
2、linux進程相關的數據結構
首先來看內核描述進程所用的數據結構。在Linux內核0.11版本中,進程數據結構的定義在sched.h文件中,定義如下
struct
task_struct {
/* these are hardcoded - don't touch */
long
state;
/*表示進程當前的狀態的字段。關于進程狀態字段相關值的定義也在shced.h文件中*/
long
counter; ? ? ? ? /*進程已用的時間片計數器*/
long
priority; ? ? ? ?/*進程優先級*/
long
signal; ? ? ? ? ? ?/*進程接收到的信號量*/
struct
sigaction sigaction[32]; ? /*sigaction與進程信號量的處理有關*/
long
blocked;
/* bitmap of masked signals */
/* various fields */
int
exit_code;
unsigned
long
start_code,end_code,end_data,brk,start_stack;
long
pid,father,pgrp,session,leader;
unsigned
short
uid,euid,suid;
unsigned
short
gid,egid,sgid;
long
alarm;
long
utime,stime,cutime,cstime,start_time;
unsigned
short
used_math;
/* file system info */
int
tty;
/* -1 if no tty, so it must be signed */
unsigned
short
umask;
struct
m_inode * pwd;
struct
m_inode * root;
struct
m_inode * executable;
unsigned
long
close_on_exec;
struct
file * filp[NR_OPEN];
/* ldt for this task 0 - zero 1 - cs 2 - ds&ss */
struct
desc_struct ldt[3];
/* tss for this task */
struct
tss_struct tss;
};
上面對task_struct的定義,又涉及到許多其它的數據結構,這里暫時就不一一列舉,隨著后面討論的深入,會逐漸在相關的部分列出來
3、Linux進程狀態state可選值有哪些與對state字段的修改
參見筆記“Linux進程狀態變化詳解”
4、進程的時間片計數器counter的初始值設定和修改
對進程couter字段初始值的設定是在fork.c中,但創建一個進程的時候,需要設定它的couter的初始值。couter的初始值就是進程的優先級數。具體的表示代碼為(fork.c的copy_process函數中,這個函數是創建子進程賦值父進程的數據時使用)
p->counter = p->priority;具體的進程的初始化將在后面討論。對counter的修改是在兩個地方,一個是在sched.c的schedule函數中,這里的修改主要是在進行進程調度時找不到合適的進程去調度(要么處于睡眠,要么counter值已經為0了),就把所有進程的counter的值都進行修改,這個地方修改counter的代碼如下
for
(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
if
(*p)
(*p)->counter = ((*p)->counter >> 1) +
(*p)->priority;
還有一個地方是在處理中斷函數中do_timer里面,將當前進程的時間片減1。代碼如下
if
((--current->counter)>0)
return
;
current->counter=0;
5、進程優先級的初始值與優先級調整
進程的優先級的初始值是設置與其父進程一樣,在fork.c中copy_process中,有這么一句*p=*current;然后,在后面剩下的部分,沒有對p的priority字段做單獨的設置,所以一個進程的優先級是與創建這個進程的父進程的優先級是一樣的。
對進程優先級做修改的一個函數是sched.c的sys_nice,這個函數的定義如下
int
sys_nice(
long
increment)
{
if
(current->priority-increment>0)
current->priority -= increment;
return
0;
}
從函數的定義來看,這個函數的作用就是根據傳入的值,來對進程的優先級進行調整,是進程的優先級降低。而sys_nice被放在了系統調用表中sys_call_table表中
6、進程信號量
常見另一篇筆記“Linux信號系統詳解”
7、進程變量
exit_code表示進程退出時代碼值,在進程退出時會根據調用exit傳遞的參數來設置exit_code的值
[進程的代碼和數據相關]
start_code、end_code、end_data、brk、start_stack表示的是進程中的代碼段、數據段、棧等信息在內存中的分布。其中start_code表示代碼段和數據段的基地址(在Linux 0.11中,代碼段和數據段共用一個段),在創建新進程的時候會設置進程的start_code的值,是一個線性地址。
end_code表示代碼段的長度,進程的end_code的設置在當使用exec系統調用執行新的程序的時候,會設定當前進程的代碼段、數據段和堆棧段的信息。在Linux 0.11中設定這個值的代碼如下(在exec.c的do_execve中)
current->brk = ex.a_bss +
(current->end_data = ex.a_data +
(current->end_code = ex.a_text));
current->start_stack = p & 0xfffff000;
ex是一個struct exec類型的變量.struct exec的定義在a.out.h中,定義如下
struct
exec {
unsigned
long
a_magic;
/* Use macros N_MAGIC, etc for access */
unsigned
a_text;
/* length of text, in bytes */
unsigned
a_data;
/* length of data, in bytes */
unsigned
a_bss;
/* length of uninitialized data area for file, in bytes */
unsigned
a_syms;
/* length of symbol table data in file, in bytes */
unsigned
a_entry;
/* start address */
unsigned
a_trsize;
/* length of relocation info for text, in bytes */
unsigned
a_drsize;
/* length of relocation info for data, in bytes */
};
因此將上述的代碼分解之后也就是
end_code=a_text; 表示代碼段的長度
end_data=a_data+a_text; 表示數據段的長度,只不過在Linux 0.11中,代碼和數據段合并為一個段,統稱為數據段了。
所以這里的end_data的值包括了end_code的部分
brk=a_bss+a_data+a_text; 進程堆的結尾字段(動態內存分配部分),brk表示進程動態堆之前的所有長度,也就是可以將brk理解成堆的開始位置
start_stack=p&0xffff000設置進程的棧的起始地址。其中p的定義為
unsigned
long
p=PAGE_SIZE*MAX_ARG_PAGES-4; PAGE_SIZE表示每一個內存頁的大小,MAX_ARG_PAGES為新程序分配給參數和環境變量使用的內存最大頁數。那么p就表示的是分配給調用進程的參數和環境變量的最大內存值,這0.11中,p的值為128KB。這樣之后,就讓start_stack指向了參數的下一頁(-4保證了start_stack不會指向參數的最后一頁,而是指向下一頁)。
對于bss部分,進程在執行新的程序的時候,會預先將一頁內存數據設為0,操作的代碼如下
i = ex.a_text+ex.a_data;
while
(i&0xfff)
put_fs_byte(0,(
char
*) (i++));
這里個人認為可以把i理解成一個邏輯地址。執行完成之后,進程的邏輯地址空間示意圖如下(具體與文件相關的細節后續另外討論)
總結
以上是生活随笔為你收集整理的在linux中进程表示的是,Linux进程的表示的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: it oracle 培训,Oracle数
- 下一篇: mips 内存 linux,MIPS 在