版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第8章Linux进程内容提要Linux进程概述进程地址空间进程控制进程优先级和调度策略守护近程8.1Linux进程概述进程概述
进程是程序的一次运行,是运行中的程序,它是处理器调度的基本单位,Linux支持多种调度策略,例如,完全公平调度和实时调度等。从进程所处的层次,进程可分为用户进程和内核线程,内核线程属于内核的一部分,用户进程最初源自加载的可执行程序。进程也是资源的拥有者和管理者,其管理的内容包括地址空间、打开的文件和身份凭证等,它们均存储于每个进程的进程控制块。进程管理的资源textdata文件描述符表stack
可执行文件实际用户ID实际用户组ID有效用户ID有效用户组ID用户标识进程与会话标识虚拟地址空间打开的文件工作目录信号开始地址结束地址缺页操作开始地址结束地址缺页操作内存区域1内存区域2用户地址空间目录项当前偏移量文件操作集文件描述进程ID父进程ID进程组ID会话ID进程标识用户身份进程控制块信号06301应用编程接口分类API功能描述用户地址空间malloc/free申请/释放动态内存brk设置堆区域的大小进程控制fork/_exit创建/终止子进程execve加载可执行二进制映像文件system执行Shell命令wait/waitpid等待子进程状态的改变进程优先给与调度策略sched_getscheduler/sched_setscheduler获取/设置进程/线程所属的调度策略sched_getparam/sched_setparam获取/设置调度参数getpriority/setpriority获取/设置进程的优先级sched_yield释放CPU的控制权sched_getaffinity/sched_setaffinity获取/设置进程的CPU亲和力openlog/closelog打开/关闭与日志系统的链接syslog记录一条日志信息8.2进程地址空间进程地址空间的划分
进程地址空间被划分为内核空间和用户空间,内核空间为内核映射,它们共享内核;用户空间源自加载的可执行程序,它们通常彼此独立。为了便于管理,用户空间被划分为若干区域,其中包括,代码区、数据区、堆、栈和mmap映射区,不同区域的功能也不相同。进程地址空间结构未初始化数据(.bss)Linux内核栈(stack)初始化数据(.data)代码(.text)0xc0000000用户虚拟地址空间堆(heap)mmap内存映射etextedataendbrk辅助信息环境变量命令行参数0x000000000x08048000文本段
代码区源自可执行文件的文本段,为程序加载时生成的内存映射,其内容为源码编译生成的指令序列和只读数据。进程运行期间,代码区内容保持不变,因此,多个运行实例可共享代码区,代码区仅需保留一份副本。数据段
数据区源自可执行文件的数据段,为程序加载时生成的内存映射,其内容为全局变量和静态变量,它被进一步分为未初始化数据区和初始化数据区。未初始化的全局变量和静态变量存储于未初始化数据区,已初始化的全局变量和静态变量存储于初始化数据区,有些编译器允许将未初始化数据和初始化数据合并成一个数据段。进程执行期间,数据区的内容可能发生改变,因此,程序的多个运行实例有各自独立的数据区。4堆(heap)堆是内核为程序运行所构建环境的一部分,它位于数据区与栈之间,用于进程的动态内存管理。例如,C/C++中的malloc/new和free/delete函数。
Linux系统中,用户进程所使用的堆由glibc实现,在可执行文件加载至用户空间时完成初始化。栈(stack)
栈同样是内核为程序运行所构建环境的一部分,它位于用户空间的底部,它是一种先进后出的数据结构,用于存放临时数据,例如,函数内的局部变量、函数参数和返回地址等。在加载程序时,会将辅助信息、环境变量和命令行参数压入栈底。其中,辅助信息以向量表的形式存储,实现信息向进程的传递。栈帧结构字符串argcargv[0]...argv[n]0environ[0]...environ[n]0...AT_NULL字符串命令行参数数量命令行参数起始地址环境变量起始地址...辅助信息向量表mmap内存映射区
mmap内存映射区位于堆和栈之间,可利用mmap函数创建,主要用于共享库的加载、共享内存和文件I/O映射等。实例分析externchar**environ;int
main(int
argc,char*argv[]){ for(intj=0;j<argc;j++)
printf("argv[%d]:%s\n",j,argv[j]); for(intj=0;environ[j];j++)
printf("environ[%d]:%s\n",j,environ[j]);exit(0);}8.3进程控制内容提要子进程的创建与终止加载可执行文件程序的启动与结束执行Shell命令监控进程状态的改变子进程的创建
子进程被创建时,内核将调用者进程拥有的资源复制给子进程,资源包括进程的用户空间和打开的文件等。为了使它们有各自的执行逻辑,内核在父进程的栈中压入子进程ID,在子进程的栈中压入0,当它们再次运行时,按各自轨迹执行。进程执行期间,可能只有少数数据被修改,为了节省资源,Linux内核采用了写时复制算法(COW)。写时复制COWstacktask_struct
datastackcodetask_struct
父进程子进程datastackcodedatacodetask_struct
task_struct
父进程子进程代码区数据区栈区代码区数据区栈区代码区数据区栈区物理页映射映射创建子进程时,父子进程共享用户地址空间父子进程的一方在修改数据前,各自生成一个拷贝创建子进程fork头文件
#include<unistd.h>函数原型
pid_tfork();功能 创建子进程。参数 无。返回值 父进程成功返回新建子进程ID, 子进程成功返回0,失败返回-1。
实例分析int glob=10;int
main(void){
intlocal;
pid_t
pid; local=8; if((pid=fork())==0){ sleep(2); }else{ glob++; local--; sleep(10); }
printf("pid=%d,glob=%d,localar=%d\n",getpid(),glob,local); exit(0);}结束进程
终止的进程进入僵尸状态,释放除返回值外的其他所有资源,等待父进程确认,父进程获得返回值后,释放其产六信息,根据返回值作相应处理。
_exit和exot函数军可用于结束进程,_exit属于核心函数,而exit属于库函数,exit建立在_exit函数基础之上,此外,还负责进程前的善后处理工作。_exit函数头文件
#include<unistd.h>函数原型
void_exit(intstatus);功能 结束进程。参数
Status:结束状态。返回值 不返回。exit函数头文件
#include<stdlib.h>函数原型
voidexit(intstatus);功能 终止进程。参数
status:返回值。返回值 无。ELF格式ELF(ExcutableandLinkableFormat)是一种可执行和可链接的格式,它源自SystemV系统,与其他格式相比,具有较强的灵活性,根据用途,可进一步分为四种类型。1.可执行文件该格式的文件可直接加载执行,由可重定位目标文件经静态链接产生。2.可重定位文件(.o文件)该格式的文件由源码经编译后生成,是一种包含重定位信息的中间代码,供链接器使用。ELF格式(续)3.共享库(.so文件)该格式的文件为源码经编译后生成地址无关的目标文件,供动态链接器在程序加载时使用。4.核心转储文件该格式的文件在信号处理时生成,为信号发生时进程的内存映像,用于程序调试。elf文件格式程序头表节头表ELF头可链接视图可执行视图段节ELF文件通常包含程序头和节头两种类型的头部结构,可从可执行和可链接两个角度描述ELF文件的内容,加载可执行文件头文件
#include<unistd.h>函数原型
int
execve(constchar*filename,char*constargv[],char*constenvp[]);功能 加载可执行文件。参数
filename:文件的路径名。
argv[]:命令行参数。
envp[]:环境变量。返回值 成功不返回,失败返回-1。加载可执行程序task_struct
文件头堆栈段数据段文本段ELF映像磁盘代码区数据区栈区栈区数据区代码区实例分析int
main(int
argc,char*argv[]){ char*newargv[]={NULL,"hello","world",NULL}; char*newenviron[]={"var1=123","var2=hello","helloUnix",NULL}; if(argc!=2){
fprintf(stderr,"Usage:%s<file-to-exec>\n",argv[0]); exit(1); } newargv[0]=argv[1]; execve(argv[1],newargv,newenviron);
perror("execve"); exit(0);}程序的启动与结束
出于编写程序的便捷性,glibc对C程序进行了封装,从程序员的角度,C程序从main函数开始运行,但事实上程序自start-up开始启动,start-up在链接生成可执行文件时引入,目的是完成一系列初始化,例如,动态内存管理的初始化,待start-up执行完成后转入main函数,最后通过exit函数结束进程,程序的运行exit库函数标准I/O文件流清理exec终止处理函数1终止处理函数n…..Linux内核exitexitexit_exit用户进程_exit_exitmain函数用户自定义函数start-up函数监控子进程状态的改变
进程运行期间状态可能会发生变化,例如,收到SIGSTOP/SIGCONT信号使进程暂停/恢复运行,因调用exit函数、从main函数返回或收到SIGTERM信号导致进程终止。为了监控子进程状态的改变,内核提供了同步和异步两种方式,若采用同步方式;进程可通过调用wait/waitpid函数,以阻塞方式等待,直至目标进程状态发生改变;若采用异步方式,当进程状态改变时,父进程会收到来自子进程的SIGCHLD信号。等待子进程状态改变头文件
#include<sys/types.h> #include<sys/wait.h>函数原型
pid_t
wait(int*wstatus);
pid_t
waitpid(pid_t
pid,int*wstatus,intoptions);功能 等待子进程状态发生改变。参数
pid:指定监控的子进程。
wstatus:返回状态。
options:操作选项。返回值
wait/waitpid成功返回状态改变的进程ID,失败返回-1。waitpid函数参数status的宏含义WIFEXITED(wstatus)若为真,子进程正常结束,调用_exit/exit函数或从main函数返回WIFSIGNALED(wstatus)若为真,子进程因信号而终止WIFSTOPPED(wstatus)若为真,子进程因信号而暂停WIFCONTINUED(wstatus)若为真,子进程因SIGCONT信号继续运行,自内核2.6.10起生效参数pid含义<−1任意进程组为-pid的子进程−1任意子进程0任意与调用者同组的子进程>0进程ID为pid的任意子进程waitpid函数中参数pid的定义waitpid函数中wstatus的宏定义8.4进程优先级和调度策略内容提要调度策略概述调度策略完全公平调度CFS实时调度策略进程的CPU亲和力调度策略概述Linux继承了Unix基于时间片的进程调度策略,但随着Linux的不断演化,进程调度策略也在不断完善,自Linux内核2.6,开始支持实时调度策略。对于多处理器环境,每个CPU有各自的就绪队列,队列可能包含多种类型的进程,与普通进程相比,实时进程拥有更高的优先级,具有优先获得CPU的权力。优先级对于不同类型的进程具有不同的含义,其定义取决于调度策略。获取/设置进程调度策略头文件
#include<sched.h>函数原型
int
sched_getscheduler(pid_t
pid);
int
sched_setscheduler(pid_t
pid,int
policy,const
struct
sched_param*param);功能 获取/设置进程的调度策略。参数
Pid:进程ID。
policy:调度策略。
param:调度参数地址。返回值
sched_getscheduler函数成功返回调度策略,失败返回-1。参数policy含义SCHED_OTHER标准时间片循环算法(CFS)SCHED_BATCH与SCHED_OTHER类似,但用于批量执行SCHED_IDLE与SCHED_OTHER类似,但优先级最低SCHED_FIFO基于先进先出的实时调度算法SCHED_RR基于时间片轮循的实时调度算法SCHED_RESET_ON_FORK创建的子进程不继承父进程的调度策略获取/设置进程调度策略头文件
#include<sched.h>函数原型
int
sched_getparam(pid_t
pid,struct
sched_param*param);
int
sched_setparam(pid_t
pid,conststruct
sched_param*param);功能 获取/设置进程的调度参数。参数
pid:进程ID。
param:调度参数的地址。返回值 成功,返回0,失败,返回-1。完全公平调度CFS
CFS(CompletelyFairScheduler)完全公平调度算法自Linux内核2.6引入,通常作为系统的默认调度算法;对于每一次轮循,每个进程均有获得处理器的机会,仅时间片大小不同,时间片的大小取决于进程的优先级。内核为每个CFS进程定义一个nice值作为优先级,其值从-20至19,默认情况下,其值为0,nice值表示进程获得时间的权重,nice值越小,每次轮循获得时间的权重越大。
CFS通常适用于交互式的个人电脑和服务器。获取/设置nice值头文件
#include<sys/resource.h>函数原型
int
getpriority(intwhich,id_twho);
int
setpriority(intwhich,id_twho,int
prio);功能 获取/设置进程的优先级级。参数
which:进程的目标类型。
who:进程身份。
prio:优先级。返回值 成功返回0,失败返回-1。实时调度策略
自内核2.6起引入了两种类型的实时调度策略。,它们均基于优先级。内核为每个实时进程赋予一个优先级,其值从1(低)至99(高),调度器按优先级从高到低依次获得CPU,高优先级进程优先获得CPU,一旦有更高优先级进程就绪,运行中的进程将立即被更高优先级进程抢占。实时调度策略(续)1.基于时间片轮循的实时调度算法该算法在优先级的基础上,对于相同优先级的进程,按时间片轮循。2.基于先进先出的实时调度算法该算法在优先级的基础上,对于相同优先级的进程,按到达的先后顺序依次执行。获取/设置实时进程优先级范围sched_get_priority_min/sched_get_priority_max函数头文件
#include<sched.h>函数原型
int
sched_get_priority_min(intpolicy);
int
sched_get_priority_max(intpolicy);功能 获取实时进程优先级的最小/最大值。参数
policy:调度策略。返回值 成功返回优先级,失败返回-1。放弃CPU的控制权sched_yield函数头文件
#include<sched.h>函数原型
int
sched_yield(void);功能 放弃CPU的控制权参数 无参数。返回值 成功,返回0,失败,返回-1。进程的CPU亲和力
在多处理器系统中,每个处理器有各自独立的调度队列,为了保持不同队列在运行期间的负载均衡,从而发挥多处理器效率,必要时,进程可在不同队列间迁移。
对于时间敏感的进程,可将其绑定至某个特定处理器,以免因迁移而造成的延期。配置进程的亲和力
sched_getaffinity/sched_setaffinity函数头文件
#include<sched.h>函数原型
int
sched_getaffinity(pid_t
pid,size_t
cpusetsize,cpu_set_t*mask)
int
sched_setaffinity(pid_t
pid,size_t
cpusetsize,const
cpu_set_t*mask);功能 获取/设置进程与CPU的绑定关系。参数
pid:进程ID。
cpusetsize:掩码字节数。
mask:绑定的CPU集合。返回值 成功返回0,失败返回-1。8.5守护近程守护进程概述
守护进程是指如同守护者一般持续在系统中运行的进程,守护进程通常具有一下特征。不手控制终端的影响。2.最多存在一个运行实例。3.必要时产生日志信息。4.修改配置后无需重启系统。守护进程的启动方式1.在系统启动时启动。2.在登录shell上启动。该方式启动的进程会继承shell的某些资源,在守护进程初始化阶段需作相应处理。创建守护进程1.切断与控制终端的联系。创建一个子进程,父进程终止,在子进程中调用setsid函数建立一个新的会话,新建会话未关联控制终端。2.关闭所有打开的文件关闭继承自父进程的所有已打开文件。3.设置根目录、工作目录和权限掩码重新设置继承自父进程的根目录、工作目录和权限掩码。完善守护进程1.处理SIGTERM信号进程结束前会收到SIGTERM信号,提醒进程作相应的善后处理。2.处理SIGHUP信号利用SIGHUP信号,重新读取修改后的配置文件。3.仅保留一个运行实例用文件锁实现仅保留一个运行实例。4.处理产生的日志利用系统提供的日志服务,保存产生的日志信息。处理SIGTERM信号
在系统关机时,所有守护进程会收到初始化进程发送的SIGTERM信号,通知守护进程在结束前做好善后处置工作
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 宝业垫付合同范例
- 双方买卖狗厂合同范例
- 保险推广合同范例
- 合法采砂船出租合同范例
- 低价购买租赁合同范例
- 徐汇附近厂房出租合同范例
- 房屋全款交易合同范例
- 买卖胶带分装合同范例
- 家具安装用工合同范例
- 家具代加工合同范例
- 2024-2025学年度第一学期四年级数学寒假作业
- 校园暴力课件
- 读后续写+旧忆新愁:办公室冷遇触发校园往事追思+讲义-2025届浙江省嘉兴市高三上学期一模英语试题
- 喷漆安全管理制度模版(3篇)
- Java Web程序设计教程(第二版)(微课版)01 Web应用开发概述
- 小学信息技术三年级上册第9课 《电子文本需保存》说课稿
- 运动解剖学(72学时)学习通超星期末考试答案章节答案2024年
- 八年级上册物理全册知识点总结(人教)
- E英语教程(第二版)1教学课件Unit-3
- 高铁乘务礼仪培训
- 仓库租赁、物资仓储保管服务投标方案(技术方案)
评论
0/150
提交评论