Linux的进程管理技术文档.docx

上传人:b****8 文档编号:9128216 上传时间:2023-02-03 格式:DOCX 页数:18 大小:91.10KB
下载 相关 举报
Linux的进程管理技术文档.docx_第1页
第1页 / 共18页
Linux的进程管理技术文档.docx_第2页
第2页 / 共18页
Linux的进程管理技术文档.docx_第3页
第3页 / 共18页
Linux的进程管理技术文档.docx_第4页
第4页 / 共18页
Linux的进程管理技术文档.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

Linux的进程管理技术文档.docx

《Linux的进程管理技术文档.docx》由会员分享,可在线阅读,更多相关《Linux的进程管理技术文档.docx(18页珍藏版)》请在冰豆网上搜索。

Linux的进程管理技术文档.docx

Linux的进程管理技术文档

第二章Linux的进程管理

●Linux是一个多任务多用户操作系统,

●一个任务(task)就是一个进程(process)。

每一个进程都具有一定的功能和权限,它们都运行在各自独立的虚拟地址空间。

●在Linux中,进程是系统资源分配的基本单位,也是使用CPU运行的基本调度单位。

§2.1Linux进程概述

一.Linux进程的组成

●存放在磁盘上的可执行文件的代码和数据的集合称为可执行映象(ExecutableImage)。

●当一个程序装入系统中运行时,它就形成了一个进程。

●进程是由正文段(text)、用户数据段(usersegment)和系统数据段(systemsegment)组成的一个动态实体。

●正文段中存放着进程要执行的指令代码,具有只读的属性,

●用户数据段是进程在运行过程中处理数据的集合,它们是进程直接进行操作的所有数据,以及进程使用的进程堆栈。

●系统数据段存放着进程的控制信息。

其中包括进程控制块PCB。

●进程控制块PCB是名字为task_struct的数据结构,它称为任务结构体

●任务结构体中容纳了一个进程的所有信息,是系统对进程进行管理和控制的有效手段,是系统实现进程调度的主要依据。

●当一个进程被创建时,系统就为该进程建立一个task_struct任务结构体。

当进程运行结束时,系统撤消该进程的任务结构体。

●进程的任务结构体是进程存在的唯一标志。

●Linux在内存空间中开辟了一个专门的区域存放所有进程的任务结构体。

●在操作系统的内核空间设置了一个task数组,该数组的每一个元素是一个指向任务结构体的指针,所以task数组又称为task向量。

structtask_struct*task[NR_TASKS]={&init_task};

#defineNR_TASKS512

全局变量nr_tasks,记录着系统中存在的进程数目。

intnr_tasks=1;

二.Linux进程的状态

1.运行态:

进程正在使用CPU运行的状态。

处于运行态的进程又称为当前进程(currentprocess)。

2.可运行态:

进程已分配到除CPU外所需要的其它资源,等待系统把CPU分配给它之后即可投入运行。

3.等待态:

又称睡眠态,它是进程正在等待某个事件或某个资源时所处的状态。

等待态进一步分为可中断的等待态和不可中断的等待态。

处于可中断等待态的进程可以由信号(signal)解除其等待态。

处于不可中断等待态的进程,一般是直接或间接等待硬件条件。

它只能用特定的方式来解除,例如使用唤醒函数wake_up()等。

4.暂停态:

进程需要接受某种特殊处理而暂时停止运行所处的状态。

通常进程在接受到外部进程的某个信号进入暂停态,例如,正在接受调试的进程就处于这种状态。

5.僵死态:

进程的运行已经结束,但它的任务结构体仍在系统中。

三.核心态和用户态

●Linux的进程处理机上运行时,处理机提供了两种不同的的执行状态,

核心态(kernelmode)和用户态(usermode)。

●核心态又称系统态,它具有较高的特权,能执行所有的机器指令,包括由操作系统执行的特权指令,能访问所有的寄存器和存储区域,能直接控制所有的系统资源。

Linux在执行内核程序时是处于核心态下。

●用户态是进程的普通执行状态,在用户态下进程具有较低的特权,只能执行规定的机器指令,不能执行特权指令。

进程在用户态下只能访问进程的存储空间。

在用户态下进程不能与系统硬件相互作用,不能访问系统资源。

四.进程空间和系统空间

●系统为每个进程分配一个独立的虚拟地址空间(虚拟内存)。

进程的虚拟地址空间被分做两个部分,用户空间和系统空间。

●用户进程本身的程序和数据(可执行映象)映射到用户空间中。

进程空间中还有进程运行用户程序时使用的堆栈,称为进程堆栈。

●系统对这个进程进行控制和管理的信息,如进程控制块等,也映射到进程空间。

●内核堆栈也在进程空间中。

●内核被映射到所有进程的系统空间中。

它们只允许在具有较高特权的核心态下访问。

进程运行在特权较低的用户态下时,不允许它直接访问系统空间。

●进程只能通过系统调用(systemcall)转换为核心态后,才能访问系统空间。

●一个进程在运行过程中,总是在两种执行状态之间不断地转换。

五.进程上下文和系统上下文

●把系统提供给进程的处于动态变化的运行环境总和称为进程上下文。

系统中的每一个进程都有它自己的上下文。

●进程因时间片用完或因等待某个事件而阻塞时,进程调度需要把CPU的使用权从当前进程交给另一个进程,这个过程称为进程切换(procdssswitching)。

●进程的切换又称为上下文切换(contextswitching).。

●在系统内核为用户进程服务,例如进程执行一个系统调用时,进程的执行状态要从用户态转换为核心态。

但是,此时内核的运行仍是进程的一部分,所以说这时内核是运行在进程上下文中。

●系统在完成自身任务时的运行环境称为系统上下文(systemcontext)。

内核在系统上下文中执行时不会阻塞。

§2.2Linux进程的任务结构体

1.进程的状态和标志

数据类型

名称

功能及作用

volatilelong

state

进程的状态

unsignedlong

flags

进程的标志

2.进程的标识

数据类型

名称

功能及作用

int

pid

进程标识号

unsignedshort

uid,gid

用户标识号,组标识号

unsignedshort

euid,egid

用户有效标识号,组有效标识号

unsignedshort

suid,sgid

用户备份标识号,组备份标识号

unsignedshort

fsuid,fsgid

用户文件标识号,组文件标识号

3.进程的族亲关系

数据类型

名称

功能及作用

structtask_struct

*p_opptr

指向祖先进程任务结构体的指针

structtask_struct

*p_pptr

指向父进程任务结构体的指针

structtask_struct

*p_cptr

指向子进程任务结构体的指针

structtask_struct

*p_ysptr

指向弟进程任务结构体的指针

structtask_struct

*p_osptr

指向兄进程任务结构体的指针

4.进程间的链接信息

数据类型

名称

功能及作用

structtask_struct

*next_task

指向下一个任务结构体的指针

structtask_struct

*prev_task

指向上一个任务结构体的指针

structtask_struct

*next_run

指向可运行队列的下一个任务结构体的指针

structtask_struct

*prev_run

指向可运行队列的上一个任务结构体的指针

5.进程的调度信息

数据类型

名称

功能及作用

long

counter

时间片计数器

long

priority

进程优先级

unsignedlong

rt_priority

实时进程的优先级

unsignedlong

policy

进程调度策略

6.进程的时间信息

数据类型

名称

功能及作用

long

start_time

进程创建的时间

long

utime

进程在用户态下耗费的时间

long

stime

进程在核心态下耗费的时间

long

cutime

所有子进程在用户态下耗费的时间

long

cstime

所有子进程在核心态下耗费的时间

unsignedlong

timeout

进程申请延时

7.进程的虚存信息

数据类型

名称

功能及作用

structmm_struct

*mm

进程的虚存信息

structdesc_struct

*ldt

进程的局部描述符表指针

unsignedlong

saved_kernel_stack

核心态下堆栈的指针

unsignedlong

kernel_stack_page

核心态下堆栈的页表指针

8.进程的文件信息

数据类型

名称

功能及作用

structfs_struct

*fs

进程的可执行映象所在的文件系统

structfiles_struct

*files

进程打开的文件

9.与进程间通信有关的信息

数据类型

名称

功能及作用

unsignedlong

signal

进程接收到的信号

unsignedlong

blocked

阻塞信号的掩码

structsignal_struct

*sig

信号处理函数表的指针

int

exit_signal

进程终止的信号

structsem_undo

semundo

进程要释放的信号量

structsem_queue

*semsleeping

与信号量操作相关的等待队列

10.其它信息

数据类型

名称

功能及作用

int

errno

系统调用的出错代码

long

debugreg[8]

进程的8个调试寄存器

char

comm[16]

进程接收到的信号

§2.3Linux的进程调度

一.Linux进程调度方式

●Linux系统采用抢占调度方式,又称可剥夺调度方式。

采用这种调度方式时,对于当前运行的进程而言,当有更紧急的进程到来时,系统将剥夺当前进程使用处理机的权利,立即停止它在处理机上的运行,而把处理机分配给那个更紧急的进程。

●Linux采用时间片轮转法。

对某个运行中的进程,当它的时间片用完时,系统将停止它的运行并把处理机分配给其它进程。

二.Linux进程调度策略

●Linux的进程分为普通进程和实时进程,实时进程的优先级高于普通进程。

●Linux对实时进程和普通进程采用不同的调度策略,在基于优先级的算法下,实时进程优先于普通进程。

●Linux进程的策略有三种,

符号常量

意义

SCHED_OTHER

普通进程的时间片轮转算法

SCHED_FIFO

实时进程的先进先出算法

SCHED_RR

实时进程的时间片轮转算法

●普通进程按照SCHED_OTHER调度策略进行进程调度。

●实时进程按照SCHED_FIFO或SCHED_RR策略进行调度。

●SCHED_FIFO是按先进先出方法选择下一个使用CPU的进程。

●SCHED_RR是实时进程的时间片轮转法策略(RoundRobin)。

三.Linux进程调度依据

●policy是进程的调度策略

SCHED_FIFO、SCHED_RR的是实时进程,

SCHED_OTHER是普通进程。

●priority是进程优先级。

它还表示分配给进程使用CPU的时间片。

●counter是进程使用CPU运行时间的计数值。

随时钟滴答减1。

counter=0时,进程的时间片已用完。

staticinlineintgoodness(structtask_struct*p,

structtask_struct*prev,intthis_cpu)

{

intweight;

if(p->policy!

=SCHED_OTHER)

return1000+p->rt_priority;

weight=p->counter;

……

……

returnweight;

}

四.Linux进程调度方法

●Linux进程调度采用动态优先级法,调度对象是可运行队列,

●可运行队列中优先级大的进程首先得到CPU投入运行。

●进程在运行中,counter的代表进程的动态优先级。

●Linux采取了加权的方法来保证实时进程优先于普通进程。

普通进程的权值就是它的counter的值,

而实时进程的权值是它的rt_priority的值加1000。

在调度过程中,调度程序检查可运行队列中所有进程的权值,

选择其中权值最大的进程做为下一个运行进程。

五.进程调度时机

时机1.进程状态发生变化时。

(1)处于运行态下的进程要等待某种资源,

(2)运行态下的进程在程序执行完毕后,一般通过调用内核函数

do_exit()终止运行并转入僵死态。

(3)处于等待态的进程被唤醒后,将加入到可运行队列中时。

(4)进程从运行态转入暂停态时。

(5)进程从暂停态成为可运行态时。

时机2.当前进程时间片用完时。

时机3.进程从系统调用返回到用户态时。

时机4.中断处理后,进程返回到用户态时。

§2.4Linux调度程序分析

§2.5Linux进程的创建

一.进程创建的原理

●系统创建的第一个进程是init进程。

●系统中所有的进程都是由当前进程使用系统调用fork()创建的。

●子进程被创建后继承了父进程的资源。

●子进程共享父进程的虚存空间。

●写时拷贝(copyonwrite):

子进程在创建后共享父进程的虚存内存空间,

只是在两个进程中某一个进程需要向虚拟内存写入数据时才拷贝相应部分

的虚拟内存。

●子进程在创建后执行的是父进程的程序代码。

●父进程执行fork()返值是子进程的PID值,子进程执行fork()的返值是0。

#include

#include

main()

{

pid_tval;

printf("PIDbeforefork():

%d\n",(int)getpid());

if(val=fork())

printf("parentprocessPID:

%d\n",(int)getpid());

else

printf("childprocessPID:

%d\n",(int)getpid());

}

该程序的执行结果:

PIDbeforefork():

490

parentprocessPID:

490

childprocessPID:

491

二.进程创建的过程

1.为新进程分配任务结构体内存空间

2.把父进程任务结构体拷贝到子进程的任务结构体

3.为新进程在其虚拟内存建立内核堆栈。

4.对子进程任务结构体中部分进行初始化设置

5.把父进程的有关信息拷贝给子进程,建立共享关系

6.把子进程的counter设为父进程counter值的一半

7.把子进程加入到可运行队列中

8.结束do_fork()函数返回PID值

三.do_fork()程序分析

§2.6等待队列及操作

一.等待队列

为了便于对等待态的进程进行管理和控制,Linux设置了等待队列和对等待队列进行操作的内核函数。

当运行态进程因等待某个事件成为等待态后,由内核函数把它插入到等待队列中。

当进程等待的事件发生后,内核函数再把它从等待队列中删除。

Linux中对应于每种等待事件都有一个等待队列。

等待态进程根据等待事件的不同排在不同的等待队列中,所以系统中通常存在着多个等待队列。

Linux的等待队列是一个由wait_queue结构体组成的循环链表。

structwait_queuq{

structtask_struct*task;

structwait-queue*next;

二.等待队列操作函数

Linux中对等待队列的操作只能使用

两个内核函数,add_wait_queue()和

remove_wait_queue()分别对等待队列

进行加入和移出操作,

三.等待队列的建立与操作

每一个等待队列都有一个指针指向该队列。

等待队列的指针被定义为静态全局变量,并被初始化为NULL。

例如:

staticstructwait_queue*event_queue=NULL;

当某个进程要加入到这个等待队列时,首先需要给该进程构造一个wait_queue结构体,例如:

structwait_queuewait;

把进程的结构体wait加入到event_queue指向的等待队列中时,调用加入等待队列函数:

add_wait_queue(&event_queue,&wait);

从event_queue指向的等待队列中删除某个进程的等待结构体wait时,调用等待队列删除函数:

remove_wait_queue(&event_queue,&wait);

§2.7进程的睡眠与唤醒

一.进程的睡眠

Linux中分别使用下列两个内核函数使进程进入不可中断等待态或可中断等待态,:

/*进程进入可中断等待态*/

voidinterruptible_sleep_on(structwait_queue**p)

{

__sleep_on(p,TASK_INTERRUPTIBLE);

}

/*进入不可中断等待态*/

voidsleep_on(structwait_queue**p)

{

__sleep_on(p,TASK_UNINTERRUPTIBLE);

}

return;

二.进程的唤醒

在等待队列中处于睡眠状态的进程,在等待的事件发生后要使用内核函数把它们唤醒。

wake_up()用于唤醒等待队列中的可中断态和不可中断态的进程,wake_up_interruptible()仅唤醒可中断态进程。

下列函数只用于唤醒可中断态的进程:

voidwake_up_interruptible(structwait_queue**q);

§2.8进程等待

一.进程等待函数及其参数

intsys_wait4(pid_tpid,unsignedint*stat_addr,intoptions,structrusage*ru)

intsys_wait3(unsignedint*stat_addr,intoptions,structrusage*ru)

intsys_waitpid(pid_tpid,unsignedint*stat_addr,intoptions)

staticinlinepid_twait(int*wait_stat)

其中sys_wait4()是内核函数,其它三个是C标准函数库中的函数。

intsys_wait4(pid_tpid,unsignedint*stat_addr,intoptions,

structrusage*ru)

pid用于指定父进程等待那种子进程:

pid<-1等待pgid与该pid绝对值相等的子进程终止。

pid=-1等待任意子进程的终止。

pid=0等待与当前进程属于同一个用户组的子进程。

pid>0等待进程标识为pid的子进程。

intsys_wait4(pid_tpid,unsignedint*stat_addr,intoptions,

structrusage*ru)

state_addr函数执行时的状态代码存放在该变量中,待函数返回时,

可以通过对这个变量的值的检测,了解到进程终止的原因:

WIFEXITED(stutas)结果为真表明进程正常终止。

WIFSIGNALED(status)结果为真表明进程因信号被终止。

WIFSTOPED(status)结果为真表明进程因信号而暂停。

intsys_wait4(pid_tpid,unsignedint*stat_addr,intoptions,

structrusage*ru)

option用于控制sys_wait4()执行方式,它的值定义:

__WCLONE:

处理由系统调用clone()生成的子进程。

WNOHANG:

sys_wait4()执行中不能被阻塞。

WUNTRACED:

处理不是因为跟踪调试的暂停态子进程。

intsys_wait4(pid_tpid,unsignedint*stat_addr,intoptions,

structrusage*ru)

ru传递的是一个structrusage结构体。

在执行sys_wait4()时,

把进程及其子进程的使用资源的有关信息写入该结构体中。

在函数返回后,可以从该结构体中得到这些信息。

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 节日庆典

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1