Linux进程概念(六):进程控制

目录

进程创建

fork函数

进程终止

终止时干了什么

进程终止的三种情况

main函数的返回值

打印默认退出码

自定义退出码

总结 

进程终止

exit函数

_exit函数

exit和_exit的区别

进程等待

什么是进程等待

为什么要有进程等待

wait函数

waitpid函数

阻塞等待与非阻塞等待

总结 


进程创建

进程 = 内核的相关管理数据结构(task_struct + mm_struct + 页表) + 代码和数据

fork函数

函数原型:pid_t

包含头文件:<unistd.h>和<sys/type.h>(后者为了适应pid_t类型的变量)

返回值:子进程中返回0,父进程返回子进程的pid,出错返回-1(进程太多等原因造成)

父进程调用fork函数,在操作系统内核执行该函数的函数体,执行时内核会做出以下反应:

  • 分配新的内存块和内核数据给子进程
  • 将父进程的部分数据结构内容拷贝至子进程,子进程共享父进程的代码,写时拷贝父进程的数据(子进程的PID、PPID、优先级与父进程等不同)
  • 添加子进程到系统列表中
  • fork返回,开始调度器调度

注意事项:
1、fork函数是操作系统内核提供的函数
2、fork前父进程独立执行,fork后父子两个执行流分别执行

3、fork之后,谁先执行完全由调度器决定

如何理解进程独立性:fork后父子进程的内核管理数据结构(页表等)互相独立,对代码是共享的(代码只有度权限不会改变),父子不写数据时相当于共享,写数据时发生写时拷贝,一人对数据的修改影响不了另一个人

如何理解fork函数有两个返回值:

如何理解调用fork函数后父进程中fork函数的返回值是子进程的pid,子进程中的fork函数的返回值是0:便于父进程对子进程进行标识,从而进行管理

fork的具体问题可以查看这篇文章:http://t.csdnimg.cn/wMBPV

进程终止

终止时干了什么

进程创建时,操作系统先为进程创建内核的相关数据结构task_struct、mm_struct、页表等,然后再加载进程的代码和数据代码(相当于大学录取后高中的学籍信息已经被大学获取,但缴费等操作是到了大学后才进行的)

那么进程终止时也应该先释放曾经的代码和数据所占据的空间,后释放内核数据结构,并让task_struct变为Z僵尸状态(相当于大学毕业后离开宿舍时将自己的东西都带走了,然后学校仍然保留你的一些关键信息存档保留一段时间)

进程终止的三种情况

main函数的返回值

  • 有返回值是因为父进程想要知道子进程运行的结果 
  • 返回值为0,表示进程运行成功
  • 返回值不为0,表示进程运行失败,不同的数字表示不同的失败原因
  • 可以使用默认的错误码,也可以自定义错误码 

打印默认退出码

C语言的sterror函数:http://t.csdnimg.cn/1HvUR 

自定义退出码

  • 结论:代码运行完后是否正确可以通过进程的退出码决定,退出码可默认可自定
  • 补充:代码执行时,出现异常导致提前退出的根本原因是因为该进程收到了OS发给它的信号
  • 信号:kill - l 查看信号找到确定退出原因

C语言的联合体和枚举:http://t.csdnimg.cn/NWYct 

总结 

1、进程终止一共有三种情况:

  • 代码跑完,结果正确
  • 代码跑完,结果不正确
  • 代码执行时,出现异常导致提前退出

2、衡量一个进程退出情况可以依据退出码和退出信号

3、子进程的pcb中有它执行完后的退出码和退出信号信息,子进程结束后,它们会跟随pcb处于Z僵尸状态等待父进程的读取,源码如下:

进程终止

进程有两种终止方式:main函数的return表示进程终止 和 调用exit或_exit函数直接退出进程

exit函数

函数原型:void exit(int status);

  • status:进程的终止原因,父进程通过wait获取
  • status仅有低8位可以被父进程所用,故_exit(-1)时,返回值是255

包含头文件:<stdlib.h>

功能:遇到exit进程直接终止,退出码即status中存放的值

int test3()
{int sum = 0;for(int i = 0; i < 50; ++i){sum += i;}exit(99);
​return sum;
}
​
int main()
{int ret =  test3();
​exit(ret);return 0;
}

[yyf@hecs-165234 linux101]$ ./myproc 
[yyf@hecs-165234 linux101]$ echo $?
99

_exit函数

函数原型:void _exit(int status);

包含头文件:<unistd.h>

注意事项:

1、_exit 是系统调用,而 exit 是库函数(C语言库函数)

2、_exit和_Exit函数本质上是同一个函数

NAME_exit, _Exit - terminate the calling process
​
SYNOPSIS#include <unistd.h>
​void _exit(int status);
​#include <stdlib.h>
​void _Exit(int status);

exit和_exit的区别

不同类型的流,默认情况下使用不同的缓存模式:

  • 行缓存模式:缓冲区中遇到\n 或者达到一定长度时自动刷新
  • 全缓存模式:关闭文件或手动调用 fflush函数前都不会进行刷新操作
  • 无缓存模式:调用stderr时,每个字符都立即被发送给终端并打印出来

结论:exit会在进程退出时冲刷缓冲区,_exit不会,因此红框例子中放在缓冲区中的字符产在调用_exit函数导致进程结束后并不会打印到显示器上,而是进程退出时与其他资源一起销毁

进程等待

什么是进程等待

1、任何进程,在退出时,一般必须要被父进程进行等待(退出信息要交给父进程)

产生问题:如果父进程不管Z状态的子进程,直接退出,则造成内存泄漏(子进程的PCB)

为什么要有进程等待

1、父进程通过等待,解决子进程退出的僵尸问题,回收系统资源(等待目标一定要释放资源)

2、获取子进程的退出信息,知道子进程是因为什么原因退出的(可以获取退出原因就更好)

wait函数

函数原型:pid_t wait(int *status)

  • 输出型数:由操作系统填充,指向子进程退出信息的整型指针,若不关心子进程的死亡原因(退出信息),可以将status设为NULL,只返回结束子进程的pid,若关心则将指定子进程的退出信息反馈给父进程(后面有详解)
  • 返回值:等待成功时为子进程的pid,等待失败时为NULL

包含头文件:<sys/types.h> 和 <sys/wait.h>

注意事项:

1、父进程一旦调用wait,就会被阻塞(挂起):

  1. 如果wait参数不为NULL,就等待指定子进程的返回,不返回父进程就一直阻塞,子进程返回后父进程会拿到子进程的退出信息并清理Z状态子进程的pcb,最后唤醒父进程
  2. 如果wait参数为NULL,只要父进程中有一个子进程结束父进程就会拿到子进程的退出信息并清理Z状态子进程的pcb,最后唤醒父进程

2、父进程的等待的本质就是在等待某种资源就绪,等到后操作系统内核就会将位于等待ZMOBIE的等待队列的父进程唤醒,并将相应信息放入int* status指向到内存空间中

对于阻塞队列的内容可以查看:http://t.csdnimg.cn/8N7Nf

waitpid函数

包含头文件:<sys/types.h> 和 <sys/wait.h>

函数原型:pid_t waitpid(pid_t pid,int *status,int options)

返回值:

  • 如果成功等到了一个子进程结束,则返回该子进程PID
  • 如果指定了WNOHANG选项,且没有任何一个子进程已经终止,则返回0
  • 如果出错(例如,指定了无效的 PID 或者调用过程被信号中断),则返回 -1

参数:

  • pid参数:为-1则表示等待任意一个子进程,不为-1则表示等待一个指定子进程

  • 输出型参数:提前开好一片内存空间,将该空间的地址传递给status,子进程返回时,操作系统会将子进程的退出信息放入该空间中

  • status参数:输出型参数,指向子进程的退出信息(退出码 + 退出信号)status是一个四字节三十二个比特位的整型变量,但是它的高两个字节(前十六个比特位)在这里不会被使用,只使用它的低16位,在低十六位中前八位表示退出码,后七位表示退出信号(后八位的最左的一位现在不解释)

打印退出信息、退出码和退出信号: 

  • 进程未受到信号干扰,顺利执行完时的退出码不为0,退出信号为0 

打印因信号终止时的退出码和退出信号:

  • 因信号导致进程终止时,退出码为0,退出信号不为0

WIFEXITED(status):子进程正常返回,则为真(查看进程是否是正常退出)

WEXITSTATUS(status):若WIFEXITED为真,查看子进程的退出码

阻塞等待与非阻塞等待

阻塞等待:父进程在等待子进程返回时什么都不做(稳定可靠)

非阻塞等待:父进程在等待子进程返回时可以去做一些事情(while循环实现)并且在做事情的间隙频繁访问子进程是否返回

waitpid的options参数的取值:

  • 0:表示当前父进程是阻塞等待
  • WNOHANG:表示当前父进程为非阻塞等待,可以与waitpid函数返回值为0时产生互动

非阻塞轮询 = 非阻塞等待 + 循环

父进程利用回调函数在阻塞轮询的时候执行自己的事情:19、1:00:00处

总结 

1、可以自定义退出码,退出信号是由操作系统提供的不能自定义

2、>>移位不会改变数字的比特位,>>=才会,0XFF表示1111 1111,0X7F表示0111 1111

3、父进程的等待是必须的,但是获取子进程的退出信息不是必须的,status设为NULL也行

  也可以参考这位大佬的文章:http://t.csdnimg.cn/syuOf 

~over~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/829505.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

环形链表——java

给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&#xff08;…

Axure实现tab页面切换功能

1. 实现效果 2. 实现原理 创建两个标签&#xff0c;并实现点击时选中状态点击时&#xff0c;设置面板状态 3. 实现步骤 3.1 实现可切换的标签 在页面上拖拽两个矩形作为两个tab标签&#xff0c;并命名 tab1 和 tab2 设置每个矩形的边框显示&#xff0c;只显示下边框即可 …

C#反射应用

1.根据类名名称生成类实例 CreateInstance后面的参数部分一定要和所构造的类参数数量对应&#xff0c;即使设置参数默认值&#xff0c;也不可省略。 2.只知道类名&#xff0c;需要将该类作为参数调用泛型接口。 3.只知道类名&#xff0c;需要将该类的数组作为参数调用泛型接口…

顺序查找和折半查找

顺序查找&#xff1a; 对于无序的情况&#xff1a; 什么是顺序查找&#xff1a;顺序查找的实现方式&#xff08;存储&#xff09;&#xff0c;是含有两种的方式进行存储的&#xff0c;一种是顺序表的形式进行存储&#xff0c;还有一种是使用链表的形式进行存储的。采用顺序查…

架构师系列- 消息中间件(15)-kafka业务实战

7.1 顺序性场景 7.1.1 场景概述 假设我们要传输一批订单到另一个系统&#xff0c;那么订单对应状态的演变是有顺序性要求的。 已下单 → 已支付 → 已确认 不允许错乱&#xff01; 7.1.2 顺序级别 1&#xff09;全局有序&#xff1a; 串行化。每条经过kafka的消息必须严格…

ElasticSearch教程入门到精通——第二部分(基于ELK技术栈elasticsearch 7.x+8.x新特性)

ElasticSearch教程入门到精通——第二部分&#xff08;基于ELK技术栈elasticsearch 7.x8.x新特性&#xff09; 1. JavaAPI-环境准备1.1 新建Maven工程——添加依赖1.2 HelloElasticsearch 2. 索引2.1 索引——创建2.2 索引——查询2.3 索引——删除 3. 文档3.1 文档——重构3.2…

react,Chart

一、基础图&#xff1a;https://ant-design-charts.antgroup.com/ Ant Design Charts 1. 首先要下载ant-design/charts&#xff0c;然后在页面中添加如下柱状图代码: import React from react; import { Column } from ant-design/chartsconst DemoColumn: React.FC () …

百度智能云千帆 ModelBuilder 技术实践系列:通过 SDK 快速构建并发布垂域模型

​百度智能云千帆大模型平台&#xff08;百度智能云千帆大模型平台 ModelBuilder&#xff09;作为面向企业开发者的一站式大模型开发平台&#xff0c;自上线以来受到了广大开发者、企业的关注。至今已经上线收纳了超过 70 种预置模型服务&#xff0c;用户可以快速的调用&#x…

深入理解冯诺依曼体系结构

文章目录 冯诺依曼体系结构概念冯诺依曼体系结构的优势冯诺依曼体系结构的现实体现 冯诺依曼体系结构概念 冯诺依曼体系结构也称普林斯顿结构&#xff0c;是现代计算机发展的基础。它的主要特点是“程序存储&#xff0c;共享数据&#xff0c;顺序执行”&#xff0c;即程序指令和…

代码随想录算法训练营Day10 | 232.用栈实现队列、225. 用队列实现栈

232.用栈实现队列 题目&#xff1a;请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾int pop() 从队列的开头移除…

【leetcode面试经典150题】75. 二叉树展开为链表(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

修改Docker容器内文件的三种方式

说明&#xff1a;本文介绍修改Docker容器内文件的三种方式 方式一&#xff1a;直接修改 敲下面的命令&#xff0c;进入Docker容器&#xff0c;如mysql docker exec -it mysql /bin/bash修改mysql的配置文件&#xff0c;/etc/my.cnf vim /etc/my.cnf如下&#xff0c;如果vim…

【Hadoop】-Apache Hive使用语法与概念原理[15]

一、数据库操作 创建数据库 create database if not exists myhive; 使用数据库 use myhive; 查看数据库详细信息 desc database myhive; 数据库本质上就是在HDFS之上的文件夹。 默认数据库的存放路径是HDFS的&#xff1a;/user/hive/warehouse内 创建数据库并指定hdfs…

attempt to compare nil with number -- 黑马点评出现问题

问题情况 : 主要问题 : 调用lua执行redis时&#xff0c;有一个值会接受nil&#xff08;因为redis中没有该数据&#xff09;或者数值&#xff0c;当该值为nil时执行报错&#xff0c;因为会用到将该值与其他数字比较&#xff0c;故报错attempt to compare nil with number 当然…

生成完美口型同步的 AI 代言人视频(及其实现原理详解)

目录 什么是Heygen? Heygen注册 Video Translation&#xff08;视频翻译 完美口型同步&#xff09; 实现原理详解 视频翻译部分 完美口型同步部分 什么是Heygen? Heygen是一款在线工具&#xff0c;可帮助您生成具有完美口型同步的 AI 代言人视频。 Heygen注册 https:…

关于springboot内置tomcat最大请求数配置的一些问题

前言 springboot内置了tomcat。那么一个springboot web应用&#xff0c;最大的请求链接数是多少呢&#xff1f;很早以前就知道这个是有个配置&#xff0c;需要的时候&#xff0c;百度一下即可。但&#xff0c;事实并非如此&#xff0c;有几个问题我想大多数人还真不知道。比如…

前端学习<四>JavaScript——54-原型链

常见概念 构造函数 构造函数-扩展 原型规则和示例 原型链 instanceof 构造函数 任何一个函数都可以被 new&#xff0c;new 了之后&#xff0c;就成了构造方法。 如下&#xff1a; function Foo(name, age) {this.name name;this.age age;//retrun this; //默认有这…

大型语言模型高效推理综述

论文地址&#xff1a;2404.14294.pdf (arxiv.org) 大型语言模型&#xff08;LLMs&#xff09;由于在各种任务中的卓越表现而受到广泛关注。然而&#xff0c;LLM推理的大量计算和内存需求给资源受限的部署场景带来了挑战。该领域的努力已经朝着开发旨在提高LLM推理效率的技术方…

C语言递归刷题(一)

目录 走台阶题目思路代码 西格玛题目思路代码 用函数实现数的阶乘题目思路代码 digit题目思路代码 Hermite多项式题目思路代码 排列数题目思路代码 逆序输出题目思路代码 结语 走台阶 题目 描述 小乐乐上课需要走n阶台阶&#xff0c;因为他腿比较长&#xff0c;所以每次可以选…

挑战特斯拉?深蓝汽车与华为强强联手

作为中国乃至全球汽车行业的盛宴&#xff0c;4月25日在中国国家展览中心揭幕的2024北京国际车展&#xff0c;吸引了无数企业行业人士的关注。 而就在车展开幕当天&#xff0c;深蓝汽车发布会就爆出了一个大新闻&#xff1a;深蓝汽车将携手华为&#xff0c;打造比特斯拉更好的智…