Linux进阶-进程
创始人
2024-02-28 11:09:13
0

目录

终端查询进程参数

进程状态

进程状态转换

子进程被Linux内核调入CPU执行的过程

子进程进入睡眠状态

子进程结束

进程控制

pid_t fork(void):创建子进程

exec()函数族:运行一个可执行文件。

void exit(int status):结束进程

wait():同步父进程与子进程

sleep(秒数):进程睡眠

进程组PGID:对相同类型的进程进行管理,由首进程PID决定

会话SID:管理进程组,由会话首进程决定

前台进程组

后台进程组

终端

守护进程

僵死进程

托孤进程


pstree:查看进程间的关系

终端查询进程参数

ps参数描述
-e列出所有进程
-f显示进程的全部信息
-h不显示进程标题列出所有进程
-l长格式显示进程
-w宽格式显示进程
-a显示终端上的所有进程,包括其他用户的进程
-r只显示正在运行的进程
-x显示没有控制终端的进程
-u显示进程的归属用户及内存使用情况
-j显示进程归属的进程组id、会话id、父进程id

ps auf(关注进程本身):用户名 PID 占用CPU% 占用内存% 虚拟内存大小 物理内存大小 进程关联的终端 进程当前状态 进程启动时间 进程运行时间 进程执行的程序。

ps axjf(关注进程间的关系):PPID PID PGID SID  进程关联的终端 是否是守护进程(-1是)  进程当前状态 用户id 进程运行时间 进程执行的程序。

进程状态

进程状态描述
创建状态进程正在被Linux内核创建
就绪进程还没有开始执行,但相关数据已被创建,只要内核调度它就立即可以执行
内核状态进程在内核状态下被运行,被调度上CPU执行
用户状态进程在用户状态下被运行,等待被调度上CPU执行
睡眠进程正在睡眠,等待系统资源或相关信号唤醒
唤醒正在睡眠的进程收到Linux内核唤醒的信号
被抢先具有更高优先级的进程强制获得进程的CPU时钟周期
僵死状态进程通过系统调用结束,进程不再存在,但在进程表项中仍有记录,该记录可由父进程收集

进程状态转换

子进程被Linux内核调入CPU执行的过程

最初,父进程通过fork系统调用创建子进程,子进程被创建后,处于创建态。Linux内核为子进程配置数据结构。如果内存空间足够,子进程在内核中就绪,否则在Swap分区就绪。这时子进程处于就绪态,等待Linux内核调度。

Linux内核会为子进程分配CPU时钟周期,在合适的时间将子进程调度上CPU运行,这时子进程处于内核态,子进程开始运行。被分配的CPU时钟周期结束时,Linux内核再次调度子进程,将子进程调出CPU,子进程进入用户态。 

待子进程被分配到下一个CPU时钟周期到来时,Linux内核又将子进程调度到CPU运行,使子进程进入内核态。如果有其他进程获得更高的优先级,子进程的时钟周期可能会被抢占,这时又回到用户态。

子进程进入睡眠状态

子进程在运行时,如果请求的资源得不到满足将进入睡眠态,睡眠态的子进程被从内存调换到Swap分区。被请求的资源可能是一个文件,也可能是打印机等硬件设备。如果该资源被释放,子进程将被调入内存,继续以系统态执行。 

子进程结束

子进程可以通过exit系统调用结束,这时子进程将进入僵死态,声明周期结束。

子进程在内核中的数据结构又被称为上下文。 

上下文:
用户级上下文是子进程用户空间的内容;
寄存器上下文是子进程运行时装入CPU寄存器的内容;
系统级上下文是子进程在Linux内核中的数据结构。

子进程切换时,CPU收到一个软中断,这时上下文将被保存起来,称之为保存现场。子进程再次运行时,上下文将还原到相关设置,称之为还原现场。整个过程称为上下文切换,保存上下文的数据空间称为u区,是Linux内核为进程分配的存储空间。

内核在以下情况会进行上下文切换操作:
子进程进入睡眠态时;
子进程时钟周期结束,被转为用户态时;
子进程再次被调度上CPU运行,转为系统态时;
子进程僵死时。

进程控制

调度时机:指进程何时被调度上CPU执行。例如,转变为睡眠态的进程将获得较高的优先级,一旦所需要的资源被释放,该进程可以立即被调度上CPU执行。被抢占的进程也将获得一个较高的优先级,抢占其CPU时钟周期的进程一旦转为用户态,被抢占的进程立即转为内核态。

调度算法:所关心的内容就是如何为进程分配优先级。

pid_t fork(void):创建子进程

在执行fork函数之前,操作系统只有一个进程,fork函数之前的代码只会被执行一次。

在执行fork函数之后,操作系统有两个几乎一样的进程,fork函数之后的代码会被执行两次。

执行完fork函数后,fork函数会返回两次。

//所需头文件
#include 
#include //函数原型
pid_t fork(void);    //创建子进程时,复制父进程的上下文
pid_t vfork(void);   //创建子进程时,不复制父进程的上下文//返回值
成功:0或其它正整数
失败:-1

首先,Linux内核在进程表中为子进程分配一个表项,然后分配PID。子进程表项的内容来自于父进程,fork系统调用会将父进程的进程表项复制为副本,并分配给子进程。然后,Linux内核使父进程的文件表和索引表的节点自增1,创建用户级上下文。最后,将父进程上下文复制到子进程的上下文空间中。fork系统调用结束后,子进程的PID被返回给父进程,而子进程获得的值为0。

exec()函数族:运行一个可执行文件。

//常见后缀
l:以列表形式传参
v:以矢量数组形式传参
p:使用环境变量Path来寻找指定执行文件
e:用户提供自定义的环境变量//所需头文件
#include //函数原型
int execl(const char *path,const char *arg,...);
int execlp(const char *file,const char *arg,...);
int execv(const char *path,char *const argv[]);
int execve(const char *path,char *const argv[],char *const envp[]);//返回值
成功:不返回
失败:-1

exec系统调用会结束原有进程,然后更新上下文的内容,并从头开始执行一个新的进程。两个进程之间并无父子关系。

void exit(int status):结束进程

//所需头文件
#include 
#include //函数原型
void exit(int status);
void _exit(int status);//返回值
不返回

进程执行exit系统调用后,Linux内核将删除进程的上下文,但保留进程表项,进程处于僵死态。待合适时,再删除进程表项的内容,释放进程PID。

wait():同步父进程与子进程

//所需头文件
#include //函数原型
pid_t wait(int *status);//返回值
成功:退出的子进程PID
失败:-1//处理子进程退出状态值的宏
WIFEXITED(status):如果子进程正常退出,则该宏为真
WEXITSTATUSA(status):如果子进程正常退出,则该宏获取子进程的退出值

系统调用wait()函数后,父进程的执行被阻断,直到子进程进入僵死态。这时,子进程的退出参数可通过wait()函数返回给父进程。wait系统调用常被用来判断子进程是否已结束。

sleep(秒数):进程睡眠

进程组PGID:对相同类型的进程进行管理,由首进程PID决定

在Shell里面直接执行一个应用程序,对于大部分进程来说,自己就是进程组的首进程,进程组只有一个进程。如果进程调用了fork函数,那么父子进程同属一个进程组,父进程为首进程。

在Shell中通过管道执行连接起来的应用程序,两个程序同属一个进程组,第一个程序为进程组的首进程。

会话SID:管理进程组,由会话首进程决定

调用setsid函数,新建一个会话,应用程序作为会话的第一个进程,称为会话首进程。

用户在终端正确登录后,启动Shell时linux系统会创建一个新的会话,Shell进程作为会话首进程。

前台进程组

Shell进程启动时,默认是前台进程组的首进程。前台进程组的首进程会占用会话所关联的终端来运行,Shell启动其他程序时,其他程序成为首进程。

在Shell进程里启动程序时,把后台进程组切换为前台进程组操作:fg jobid

后台进程组

后台进程中的程序徐不会占用终端。

jobs:查看有哪些后台进程组。

在Shell进程里启动程序时,指定程序运行在后台进程组操作:&、Ctrl+Z。

终端

当终端被关闭之后,会话中的除守护进程外的所有进程都会被关闭。

物理终端:串口终端、LCD终端

伪终端:SSH远程连接产生的终端、桌面系统启动的终端

虚拟终端:Linux内核自带,Ctrl+Alt+F0~F6可以打开7个虚拟终端

守护进程

创建子进程,父进程直接退出(父进程放弃终端使用权)。fork()函数。

创建新会话,不关联任何终端。setsid()函数。

改变守护进程的当前工作目录,改为“/”。chdir()函数。

重设文件权限掩码,新建文件的权限受文件权限掩码影响。umask()函数

关闭默认的文件描述符。close()函数。

实现守护进程的功能。

普通程序伪装成守护进程:nohup

僵死进程

进程正常退出:
子进程调用exit()函数退出
父进程调用wait()函数为子进程处理其他事情

子进程调用exit()函数退出,父进没有调用wait()函数为子进程处理其他事情,子进程就变成僵死进程。

托孤进程

父进程比子进程先退出(_exit()可立即退出进程),子进程变为孤儿进程,Linux系统会把子进程托孤给1号进程(init进程)。

相关内容

热门资讯

常用商务英语口语   商务英语是以适应职场生活的语言要求为目的,内容涉及到商务活动的方方面面。下面是小编收集的常用商务...
六年级上册英语第一单元练习题   一、根据要求写单词。  1.dry(反义词)__________________  2.writ...
复活节英文怎么说 复活节英文怎么说?复活节的英语翻译是什么?复活节:Easter;"Easter,anniversar...
2008年北京奥运会主题曲 2008年北京奥运会(第29届夏季奥林匹克运动会),2008年8月8日到2008年8月24日在中华人...
英语道歉信 英语道歉信15篇  在日常生活中,道歉信的使用频率越来越高,通过道歉信,我们可以更好地解释事情发生的...
六年级英语专题训练(连词成句... 六年级英语专题训练(连词成句30题)  1. have,playhouse,many,I,toy,i...
上班迟到情况说明英语   每个人都或多或少的迟到过那么几次,因为各种原因,可能生病,可能因为交通堵车,可能是因为天气冷,有...
小学英语教学论文 小学英语教学论文范文  引导语:英语教育一直都是每个家长所器重的,那么有关小学英语教学论文要怎么写呢...
英语口语学习必看的方法技巧 英语口语学习必看的方法技巧如何才能说流利的英语? 说外语时,我们主要应做到四件事:理解、回答、提问、...
四级英语作文选:Birth ... 四级英语作文范文选:Birth controlSince the Chinese Governmen...
金融专业英语面试自我介绍 金融专业英语面试自我介绍3篇  金融专业的学生面试时,面试官要求用英语做自我介绍该怎么说。下面是小编...
我的李老师走了四年级英语日记... 我的李老师走了四年级英语日记带翻译  我上了五个学期的小学却换了六任老师,李老师是带我们班最长的语文...
小学三年级英语日记带翻译捡玉... 小学三年级英语日记带翻译捡玉米  今天,我和妈妈去外婆家,外婆家有刚剥的`玉米棒上带有玉米籽,好大的...
七年级英语优秀教学设计 七年级英语优秀教学设计  作为一位兢兢业业的人民教师,常常要写一份优秀的教学设计,教学设计是把教学原...
我的英语老师作文 我的英语老师作文(通用21篇)  在日常生活或是工作学习中,大家都有写作文的经历,对作文很是熟悉吧,...
英语老师教学经验总结 英语老师教学经验总结(通用19篇)  总结是指社会团体、企业单位和个人对某一阶段的学习、工作或其完成...
初一英语暑假作业答案 初一英语暑假作业答案  英语练习一(基础训练)第一题1.D2.H3.E4.F5.I6.A7.J8.C...
大学生的英语演讲稿 大学生的英语演讲稿范文(精选10篇)  使用正确的写作思路书写演讲稿会更加事半功倍。在现实社会中,越...
VOA美国之音英语学习网址 VOA美国之音英语学习推荐网址 美国之音网站已经成为语言学习最重要的资源站点,在互联网上还有若干网站...
商务英语期末试卷 Part I Term Translation (20%)Section A: Translate ...