在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理解成一个逻辑地址。执行完成之后,进程的逻辑地址空间示意图如下(具体与文件相关的细节后续另外讨论)

1724a6b55cc5d2a96aa4412f19bb4393.png

5251820.htm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值