Linux系统编程-进程

发布时间:2021-05-16 10:13:29



文章目录
第一章 进程相关概念第二章 程序和进程第三章 并发第四章 单道程序设计第五章 多道程序设计第六章 CPU和MMU第七章 进程控制块PCB第七章 进程控制块PCB第八章 进程状态第八章 进程状态第九章 环境变量第九章 环境变量第十章 进程状态函数第十一章 进程共享第十二章 回收子进程第十三章 孤儿进程第十四章 僵尸进程




第一章 进程相关概念


第二章 程序和进程

程序:程序,是指编译好的二进制文件,在磁盘上,不占用系统资源(cpu、内存、打开的文件、设备、锁....)

进程:是一个抽象的概念,与操作系统原理联系紧密。进程是活跃的程序,占用系统资源。在内存中执行。(程序运行起来,产生一个进程)

程序 → 剧本(纸)、进程 → 戏(舞台、演员、灯光、道具…),同一个剧本可以在多个舞台同时上演。同样,同一个程序也可以加载为不同的进程(彼此之间互不影响)如:同时开两个终端。各自都有一个bash但彼此ID不同

第三章 并发

并发,在[操作系统](http://baike.baidu.com/view/880.htm)中,一个时间段中有多个进程都处于已启动运行到运行完毕之间的状态。但,任一个时刻点上仍只有一个进程在运行。

例如,当下,我们使用计算机时可以边听音乐边聊天边上网。 若笼统的将他们均看做一个进程的话,为什么可以同时运行呢,因为并发。


第四章 单道程序设计

所有进程一个一个排对执行。若A阻塞,B只能等待,即使CPU处于空闲状态。而在人机交互时阻塞的出现时必然的。所有这种模型在系统资源利用上及其不合理,在计算机发展历史上存在不久,大部分便被淘汰了。


第五章 多道程序设计

在计算机内存中同时存放几道相互独立的程序,它们在管理程序控制之下,相互穿插的运行。多道程序设计必须有[硬件基础](http://baike.baidu.com/view/4419390.htm)作为保证。

**时钟中断**即为多道程序设计模型的理论基础。 并发时,任意进程在执行期间都不希望放弃cpu。因此系统需要一种强制让进程让出cpu资源的手段。时钟中断有硬件基础作为保障,对进程而言不可抗拒。 操作系统中的中断处理函数,来负责调度程序执行。

在多道程序设计模型中,多个进程轮流使用CPU (分时复用CPU资源)。而当下常见CPU为纳秒级,1秒可以执行大约10亿条指令。由于人眼的反应速度是毫秒级,所以看似同时在运行。
1s = 1000ms, 1ms = 1000us, 1us = 1000ns 1000000000

实质上,并发是宏观并行,微观串行! -----推动了计算机蓬勃发展,将人类引入了多媒体时代。

第六章 CPU和MMU

中央处理器(CPU)

内存管理单元MMU

MMU简易页表


第七章 进程控制块PCB


第七章 进程控制块PCB

我们知道,每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息,Linux内核的进程控制块是task_struct结构体。

/usr/src/linux-headers-3.16.0-30/include/linux/sched.h文件中可以查看struct task_struct 结构体定义。其内部成员有很多,我们重点掌握以下部分即可:

进程id。系统中每个进程有唯一的id,在C语言中用pid_t类型表示,其实就是一个非负整数。进程的状态,有就绪、运行、挂起、停止等状态。进程切换时需要保存和恢复的一些CPU寄存器。描述虚拟地址空间的信息。描述控制终端的信息。当前工作目录(Current Working Directory)。umask掩码。文件描述符表,包含很多指向file结构体的指针。和信号相关的信息。用户id和组id。会话(Session)和进程组。进程可以使用的资源上限(Resource Limit)。
第八章 进程状态


第八章 进程状态

进程基本的状态有5种。分别为 初始态 => 就绪态 => 运行态 => 挂起态 => 终止态。其中初始态为进程准备阶段,常与就绪态结合来看。


第九章 环境变量


第九章 环境变量

    环境变量,是指在操作系统中用来指定操作系统运行环境的一些参数。通常具备以下特征:


    字符串(本质) ② 有统一的格式:名=值[:值] ③ 值用来描述进程环境信息。存储形式:与命令行参数类似。char *[]数组,数组名environ,内部存储字符串,NULL作为哨兵结尾。使用形式:与命令行参数类似。加载位置:与命令行参数类似。位于用户区,高于stack的起始位置。引入环境变量表:须声明环境变量。extern char ** environ;

    常见的环境变量

    按照惯例,环境变量字符串都是name=value这样的形式,大多数name由大写字母加下划线组成,一般把name的部分叫做环境变量,value的部分则是环境变量的值。环境变量定义了进程的运行环境,一些比较重要的环境变量的含义如下:


    PATH 可执行文件的搜索路径。ls命令也是一个程序,执行它不需要提供完整的路径名/bin/ls,然而通常我们执行当前目录下的程序a.out却需要提供完整的路径名./a.out,这是因为PATH环境变量的值里面包含了ls命令所在的目录/bin,却不包含a.out所在的目录。PATH环境变量的值可以包含多个目录,用:号隔开。在Shell中用echo命令可以查看这个环境变量的值:echo $PATHSHELL 当前Shell,它的值通常是/bin/bash echo $SHELLTERM 当前终端类型,在图形界面终端下它的值通常是xterm,终端类型决定了一些程序的输出显示方式,比如图形界面终端可以显示汉字,而字符终端一般不行 echo $TERMLANG 语言和locale,决定了字符编码以及时间、货币等信息的显示格式 echo $LANGHOME 当前用户主目录的路径,很多程序需要在主目录下保存配置文件,使得每个用户在运行该程序时都有自己的一套配置 echo $HOME

    环境变量相关函数


    getenv() 获取环境变量值
    函数原型:char *getenv(const char *name);
    成功:返回环境变量的值;失败:NULL (name不存在)setenv() 设置环境变量的值
    函数原型:int setenv(const char *name, const char *value, int overwrite); 参数overwrite=[1(覆盖原环境变量)|0(不覆盖)],该参数常用于设置新环境变量,如:ABC = haha-day-night。
    成功:0;失败:-1unsetenv() 删除环境变量name的定义
    函数原型:int unsetenv(const char *name);
    成功:0;失败:-1
    注意事项:name不存在仍返回0(成功),当name命名为"ABC="时则会出错。

第十章 进程状态函数

    创建一个子进程 fork()
    pid_t fork(void);
    失败返回-1;成功返回:① 父进程返回子进程的ID(非负) ②子进程返回 0 (注意返回值,不是fork函数能返回两个值,而是fork后,fork函数变为两个,父子需【各自】返回一个)

    pid_t类型表示进程ID,但为了表示-1,它是有符号整型。(0不是有效进程ID,init最小,为1)


    循环创建N个子进程
    一次fork函数调用可以创建一个子进程。那么创建N个子进程应该怎样实现呢?

    简单想,for(i = 0; i < n; i++) { fork() } 即可。但这样创建的是N个子进程吗?
    从上图我们可以很清晰的看到,当n为3时候,循环创建了(2^n)-1个子进程,而不是N的子进程。需要在循环的过程,保证子进程不再执行fork ,因此当(fork() == 0)时,子进程应该立即break;才正确。

    练*:通过命令行参数指定创建进程的个数,每个进程休眠1S打印自己是第几个被创建的进程。如:第1个子进程休眠0秒打印:“我是第1个子进程”;第2个进程休眠1秒打印:“我是第2个子进程”;第3个进程休眠2秒打印:“我是第3个子进程”。通过该练*掌握框架:循环创建n个子进程,使用循环因子i对创建的子进程加以区分。

    getpid() 获取当前进程ID
    pid_t getpid(void);

    getppid() 获取当前进程的父进程ID
    pid_t getppid(void);
    区分一个函数是“系统函数”还是“库函数”依据:是否访问内核数据结构;是否访问外部硬件资源 二者有任一 → 系统函数;二者均无 → 库函数

    getuid() 获取当前进程实际用户ID
    uid_t getuid(void);

    geteuid() 获取当前进程有效用户ID
    uid_t geteuid(void);

    getgid() 获取当前进程使用用户组ID
    gid_t getgid(void);

    getegid() 获取当前进程有效用户组ID
    gid_t getegid(void);

    进程执行相关函数(有六种以exec开头的函数,统称exec函数)


    exec() fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。将当前进程的.text、.data替换为所要加载的程序的.text.data,然后让进程从新的.text第一条指令开始执行,但进程ID不变,换核不换壳。execlp() 加载一个进程,借助PATH环境变量
    int execlp(const char *file, const char *arg, …);(参数1:要加载的程序的名字。该函数需要配合PATH环境变量来使用,当PATH中所有目录搜索后没有参数1则出错返回。该函数通常用来调用系统程序。如:ls、date、cp、cat等命令)
    成功:无返回;失败:-1execl() 加载一个进程, 通过 路径+程序名 来加载。
    int execl(const char *path, const char *arg, …);
    成功:无返回;失败:-1
    对比execlp,如加载"ls"命令带有-l,-F参数execlp(“ls”, “ls”, “-l”, “-F”, NULL); 使用程序名在PATH中搜索。execl("/bin/ls", “ls”, “-l”, “-F”, NULL); 使用参数1给出的绝对路径搜索。execvp() 加载一个进程,使用自定义环境变量env
    int execvp(const char *file, const char *argv[]);(变参形式: ①… ② argv[] (main函数也是变参函数,形式上等同于 int main(int argc, char *argv0, …)), 变参终止条件:① NULL结尾 ② 固参指定)
    execvp与execlp参数形式不同,原理一致。练*:将当前系统中的进程信息,打印到文件中。int execle(const char *path, const char *arg, …, char *const envp[]);int execv(const char *path, char *const argv[]);int execve(const char *path, char *const argv[], char *const envp[]);

    execl 函数族一般规律:exec函数一旦调用成功即执行新的程序,不返回。只有失败才返回,错误值**-1**。所以通常我们直接在exec函数调用后直接调用perror()和exit(),无需if判断。
    l (list) 命令行参数列表
    p (path) 搜素file时使用path变量
    v (vector) 使用命令行参数数组
    e (environment) 使用环境变量数组,不使用进程原有的环境变量,设置新加载程序运行的环境变量

    事实上,只有execve是真正的系统调用,其它五个函数最终都调用execve,所以execve在man手册第2节,其它函数在man手册第3节。这些函数之间的关系如下图所示。

    进程阻塞、关闭相关函数


    wait() 一个进程在终止时会关闭所有文件描述符,释放在用户空间分配的内存,但它的PCB还保留着,内核在其中保存了一些信息:如果是正常终止则保存着退出状态,如果是异常终止则保存着导致该进程终止的信号是哪个。这个进程的父进程可以调用wait或waitpid获取这些信息,然后彻底清除掉这个进程。我们知道一个进程的退出状态可以在Shell中用特殊变量$?查看,因为Shell是它的父进程,当它终止时Shell调用wait或waitpid得到它的退出状态同时彻底清除掉这个进程。

    父进程调用wait函数可以回收子进程终止信息。该函数有三个功能:阻塞等待子进程退出;回收子进程残留资源;获取子进程结束状态(退出原因)。

    pid_t wait(int *status);

    成功:清理掉的子进程ID;失败:-1 (没有子进程)

    当进程终止时,操作系统的隐式回收机制会:1.关闭所有文件描述符 2. 释放用户空间分配的内存。内核的PCB仍存在。其中保存该进程的退出状态。(正常终止→退出值;异常终止→终止信号)

    可使用wait函数传出参数status来保存进程的退出状态。借助宏函数来进一步判断进程终止的具体原因。宏函数可分为如下三组:


      WIFEXITED(status) 为非0 → 进程正常结束

      WEXITSTATUS(status) 如上宏为真,使用此宏 → 获取进程退出状态 (exit的参数)

      WIFSIGNALED(status) 为非0 → 进程异常终止

      WTERMSIG(status) 如上宏为真,使用此宏 → 取得使进程终止的那个信号的编号。

      WIFSTOPPED(status) 为非0 → 进程处于暂停状态

    WSTOPSIG(status) 如上宏为真,使用此宏 → 取得使进程暂停的那个信号的编号。

    WIFCONTINUED(status) 为真 → 进程暂停后已经继续运行

    waitpid() 作用同wait,但可指定pid进程清理,可以不阻塞。

    pid_t waitpid(pid_t pid, int *status, in options);(参数pid: >0 回收指定ID的子进程 | 0 回收和当前调用waitpid一个组的所有子进程 | -1 回收任意子进程(相当于wait)| < -1 回收指定进程组内的任意子进程)

    成功:返回清理掉的子进程ID;失败:-1(无子进程), 返回0:参3为WNOHANG,且子进程正在运行。

    注意:一次wait或waitpid调用只能清理一个子进程,清理多个子进程应使用循环。

    作业:父进程fork 3 个子进程,三个子进程一个调用ps命令, 一个调用自定义程序1(正常),一个调用自定义程序2(会出段错误)。父进程使用waitpid对其子进程进行回收。


第十一章 进程共享


第十二章 回收子进程


第十三章 孤儿进程

孤儿进程: 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为init进程,称为init进程领养孤儿进程。

第十四章 僵尸进程

僵尸进程: 进程终止,父进程尚未回收,子进程残留资源(PCB)存放于内核中,变成僵尸(Zombie)进程。 【zoom .c】

特别注意,僵尸进程是不能使用kill命令清除掉的。因为kill命令只是用来终止进程的,而僵尸进程已经终止。思考!用什么办法可清除掉僵尸进程呢?

相关文档

  • HandleThread面试详解
  • QT IP输入框的实现
  • 微软确认裁员300多人,主要波及雷德蒙德总部
  • 创城我们在行动演讲稿范文
  • 四年级语文一单元的测试卷总结
  • 飞机液体携带有什么规定
  • 体育基础知识试题及答案
  • 新员工工作多长时间才有年假
  • 朋组词是什么
  • 苏教版《狼和小羊》优秀教案
  • Gartner:2019年PaaS四大趋势
  • 小学校本课程实施方案 校本课程实施方案8篇
  • 数组实现顺序表和顺序表的插入
  • 建筑工程面积学术论文
  • 关于播音主持必练的中文绕口令
  • 那天阳光真暖作文
  • 养颜美容必吃的食物
  • 解决 SpringBoot + Vue 跨域问题
  • 女生个性签名霸气学校
  • 有种幸福叫疼痛阅读答案
  • 用不足为凭怎么造句
  • 赤壁赋答案
  • 怯懦的句子
  • 初中好友的毕业留言语
  • 乡镇领导班子个人评价
  • 婚礼男方家长发言稿集锦3篇
  • 实用的过新年作文400字6篇
  • 关于人性的寓言故事
  • 白领秋季养生常识十大事项必知
  • 写友情的短文章
  • 猜你喜欢

  • 2018-2019年贵阳市乌当区东风镇头堡小学一年级上册语文练习题无答案
  • 《端午粽》公开课教学PPT课件--(统编教材·部编新人教版小学语文一年级下册)
  • 8篇《谁动了我的奶酪》读后感
  • 高中历史第7单元1861年俄国农奴制改革第2课农奴制改革的主要内容课件新人教版选修1
  • 质量环境职业健康安全管理体系培训下3
  • 苹果6plus应用商店怎么不是中文
  • 初中初二作文日记:我好想长大
  • 给朋友英文道歉信
  • 徐汇8个美景(诗联)
  • 大连市鹏泰商贸有限公司企业信用报告-天眼查
  • 小学数学课堂教学中人文素养的渗透
  • 江西省2016年中考地理中等学校招生考试地理信息训练试题
  • 初中生应把握中考英语作文的评分标准
  • 2018-2019学年最新苏科版八年级数学上册教案:3.3勾股定理的简单应用-优质课教案
  • 体寒患者选水果时要谨慎
  • 2019届四川省成都市第七中学高三一诊模拟考试数学(文)试题(word版)
  • 模袋混凝土正堤防加固中的应用及其质量控制
  • 2015年度潜江市心辉粮食收购加工厂销售收入与资产数据报告
  • 新疆公安机关“大教育、大培训”工作酮?嵩谝晾缏≈卣倏
  • [心理测试关于爱情] 爱情测试题他爱我吗
  • android仿小红书图片拖拽(改进版,仿微信朋友圈拖拽删除)
  • 2017-2022年中国消防应急灯行业市场研究及投资战略预测报告(目录)
  • 北京导游词:六大景点英文导游词之天坛
  • 【精品推荐】冲厕所如何节水
  • 市优质护理服务示范病房考核标准
  • 初一春节见闻作文500字三篇
  • 我的小猪存钱罐小学生作文
  • 【最新2018】初三数学复*常见误区-实用word文档 (2页)
  • 白山市浑江区众鑫现代化苗木培育基地(企业信用报告)- 天眼查
  • 【教育学*文章】在地区三级干部会议上的致辞
  • 【最新文档】商场某专柜广播稿大全-word范文 (2页)
  • Android技巧:学习使用GridLayout
  • 给小学毕业学生的寄语
  • 2018年秋七年级数学上册北师大版*题课件:第四章测试卷(共28张PPT)
  • 动态规划详解
  • 环球插件机操作指导书
  • 人因梦想而伟大的演讲稿范文1100字
  • 2017-2023年中国防弹运钞车市场发展策略及投资潜力可行性预测报告(目录)
  • 2019-2020学年高中物理第4章机械能和能源第4节机械能守恒定律教师用书粤教版
  • 国家标准-太阳能热水器命名规则及含义
  • 高校数学建模教学模式的探索以及实践
  • JAVA资深架构师成长路线->分布式方案>单点登陆方案
  • 电脑版