面试常问的《进程创建—进程终止—进程等待—进程替换》!

news2024/11/19 5:47:22

送给正在努力前行的你一句话:要努力,但不要着急,繁花锦簇,硕果累累都需要过程

博主主页

目录

1.进程创建

fork函数初识

fork函数返回值

写时拷贝

2.进程终止

进程退出场景

进程如何退出

3.进程等待

进程等待的必要性

进程等待的方法

4.进程程序替换

1.进程创建

fork函数初识

在Linux中fork函数是从一个已经存在的进程中创建一个新的进程,新的进程被称为子进程,而原进程称为父进程。

#include<unistd.h>
pid_t id = fork()

返回值:有两个返回值,给父进程返回子进程的pid,给子进程返回0,创建失败返回-1

 

进程调用fork函数之后:

分配新的内存块和内核数据结构给子进程

将父进程部分数据结构内容拷贝到子进程

fork函数返回值

为什么fork函数有两个返回值?

保证进程的独立性

如何理解给父进程返回子进程的pid,给子进程返回0?

因为父进程是具有唯一性的,通过子进程能够找到父进程

如何理解同一个id值会保存两个值,让if,else同时执行?

fork函数在返回之前就已经创建好子进程分流开始调度了

写时拷贝

通常,父子代码共享,父子再不写入时,数据也是共享的,当任意一方试图写入,便以写时拷贝的方式各自一份副本。

2.进程终止

进程退出场景

#include<stdio.h>
int main()
{
    return 0;
}

为什么main函数结束之后要返回0呢?

答案:0是进程退出的时候对应的退出码

退出码:0表示正常退出,非0表示进程失败

非0具体是几,表示不同的错误

查看退出码:

 

命令行查看进程退出码:

echo $?:返回运行记录最近一个进程在命令行中执行完毕时对应的退出码 

进程如何退出

1.main函数return返回

 2.任意地方调用exit(退出码)_exit(退出码)

exit和_exit的区别:

1.exit头文件:#include<stdlib.h>

_exit头文件:#include<unistd.h>

2.运行这段代码:exit

 sleep两秒之后打印出“hello world”

_exit运行这段代码:

 sleep两秒之后没有打印出任何结果

所以exit和_exit的区别是:

exit终止进程主动刷新缓冲区,_exit终止进程不会主动刷新缓冲区

3.exit是库函数,_exit是系统调用接口

3.进程等待

进程等待的必要性

子进程退出,如果父进程不进行回收,那么子进程就可能会成为僵尸进程,一旦成为僵尸进程操作系统也没有办法终止掉该进程,此时就有可能会造成内存泄漏的问题,同时也无法得知该进程将任务完成的如何!

因此对于上面这种问题必须通过进程等待的方式,让父进程回收子进程的资源,获取子进程的退出信息。

进程等待的方法

wait方法:

#include<sys/types.h>
#include<sys/wait.h>

pid_t wait(int*status);

返回值:

成功返回被等待进程的pid,失败返回-1

参数:

输出型参数,获取子进程退出状态,不关心可以设置为NULL

验证父进程回收子进程的过程:

 这段代码的含义是:用fork创建子进程,然后让子进程跑10秒钟,让父进程休眠15秒,所以中间就会有5秒子进程处于僵尸状态,因为父进程没有回收子进程,5秒后wait等待成功,然后被父进程回收了

waitpid方法:

#include<sys/types.h>
#include<sys/wait.h>
pid_ t waitpid(pid_t pid, int *status, int options);

返回值:

等待成功返回子进程的pid

参数:

pid

pid=-1,等待任意一个进程,与wait等效

pid>0,等待子进程id与pid相同的进程

status:查看子进程退出时的状态信息

 

通过运行后可以观察到,等待成功之后返回子进程的pid,但是并没有通过status正确获取到子进程终止时的状态信息 ,因为在进程退出的时候我们将子进程终止时的状态信息设置为10,而status拿的是2560.这是因为我们不能将status当作一个整数来看待,因为status有自己的位图结构

获取进程终止时的状态信息:就需要拿到status二进制中的次8位

获取方法:(status>>8) & 0xFF

获取进程终止的信号:就需要拿到status二进制中的前7位 

获取方法:status &0x7F 

此时我们就成功获取到了进程退出时的状态信息和终止信号;

注:当进程正常终止的时候终止信号就为0,如果进程异常被操作系统异常终止就会显示进程异常终止的对应信号

进程异常终止的信号:

 

当进程中存在野指针的问题时,进程异常,被操作系统终止,终止信号就为11代表段错误,而我们的进程也没有正常运行完,所以status也没有获取到次8位的值,我们默认异常终止状态信息设置为0

status获取进程退出时的状态信息第二种方式:宏

WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)
WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)

 options:

 1.设置为0表示阻塞式等待,当子进程没有退出的时候,父进程一直在等待子进程,直到等待成功,释放子进程:

2.设置为WNOHANG,表示为阻塞式等待,父进程会检测子进程是否退出的状态,如果子进程没有退出,则父进程不会继续等待子进程,而是继续执行其它的操作,但是如果非阻塞式等待第一次子进程没有退出,则可能会造成父进程先释放,子进程变成孤儿进程,所以对于非阻塞式等待一般采用轮询的方式进行等待!

 

为什么会存在非阻塞式等待:当父进程在轮询式等待的过程中,子进程并不会占用父进程的资源,因此父进程可以做其它的事情:

例:

4.进程程序替换

概念:

将指定的程序加载到内存,让指定的进程执行

所以进程程序替换完成包括两个步骤:1.找到要执行的程序,2.要如何执行

进程程序替换的方法:

通过函数调用来实现的:

#include <unistd.h>`
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);

例:通过调用execl这个函数,让我们的进程执行ls这个命令

此时就完成了我们自己写的进程执行别的程序,这就是一次程序替换

execlp函数介绍:

功能:只需要在调用函数的时候传需要执行哪个程序,就自动会在环境变量PATH中查找

execv函数介绍:

 功能:可以将所有的可执行参数放入到数组中统一传递,而不用使用可变参数方案:

execvp函数介绍:

 功能:不需要带路径,只需要传调用谁,就自动会在环境变量PATH中查找:

execle函数介绍:

 功能:可以将环境变量传到子进程中

mybin.c:

 myexec.c:

 

注:这五个函数都不是系统调用接口,而是基于execve这个系统调用接口进行封装的

进程程序替换的本质

验证:

 

运行发现,输出了start,但是没有输出end,说明在调用execl函数之后,原来进程的代码和数据被覆盖了 

为什么要进行程序替换

因为进程具有独立性,因此可以通过程序替换的方式让子进程执行一个全新的程序:

进程替换的使用场景:

模拟实现一个简易的shell:

 

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

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

相关文章

Java泛型简介

参考博客&#xff1a;https://www.jb51.net/article/192850.htm 泛型&#xff0c;即“参数化类型”。一提到参数&#xff0c;最熟悉的就是定义方法时有形参&#xff0c;然后调用此方法时传递实参。那么参数化类型怎么理解呢&#xff1f;顾名思义&#xff0c;就是将类型由原来的…

vuex持久化

下载&#xff1a; vuex-persistedstate npm install --save vuex-persistedstate 或者&#xff1a; npm install --save vuex-persistedstate --legacy-peer-deps 引入使用&#xff1a;在store文件夹下的index文件中&#xff0c;也就是放vuex的js代码中引入&#xff1a; i…

周末福利 | 21天学通Python完整版,豆瓣评分9.6!

前言 又到了周末啦&#xff0c;小编例行给大家发福利&#xff01; 今天福利的内容是21天学通Python完整版&#xff0c;这是一本豆瓣评分9.6的人工智能入门书籍&#xff01;全面、系统、深入地讲解了Python编程基础语法与高级应用。在讲解过程中&#xff0c;通过大量实际操作的…

mac m1 安装docker docker 安装php 5.6 和 7.2 避坑指南

通过该link可以下载兼容mac m1核心的docker-desktop: Docker Desktop - Docker 所有基于amd64架构核心的都加上--platform linux/amd64来运行,这样就能愉快的玩耍了: docker search centos7 php56 #搜索 docker images #显示所有镜像 docker pull sglim2/centos7 建议使用ln…

如何让青少年在AI时代抢占先机

点击蓝字关注我们AI TIME欢迎每一位AI爱好者的加入&#xff01;11月17日&#xff0c;由智谱AI支持&#xff0c;北京市科委、中关村管委会科普专项经费资助的系列栏目“科普大佬说”很荣幸邀请到国家科技部“新一代人工智能创新发展与应用研究”项目、中小学人工智能教育服务平台…

在VSCode中用Markdown自动生成PPT详细使用指南,支持多种风格和排版,支持ppt转为pdf等

在VSCode中用Markdown自动生成PPT详细使用指南&#xff0c;支持多种风格和排版&#xff0c;支持ppt转为pdf等。 Marp 官网&#xff1a; https://marp.app/ 这款软件也能在 Windows 或 Linux 系统上使用&#xff0c;并不局限于 macOS 系统。 今天要介绍的是 Marp 推出的 VS Cod…

PLC-Recorder实现速度高达0.24ms准确周期采集的方法(带时间戳采集)

目录 1、PLC的发送程序 2、PLC连接配置 3、PLC-Recorder侧的通讯设置 4、PLC-Recorder的通道配置 5、PLC-Recorder的变量配置 6、正常通讯情况的界面 7、记录数据的情况 8、小结 如果要以非常高的速度高速采集各种控制器&#xff08;典型的是PLC&#xff09;的数据&…

【Linux】gcc/g++

目录 Linux编译器-gcc/g使用 No.1 背景知识 No.2 预处理(进行宏替换) No.3 编译&#xff08;生成汇编&#xff09; No.4 汇编&#xff08;生成机器可识别代码&#xff09; No.5 动态链接过程 No.6 gcc选项 Linux编译器-gcc/g使用 No.1 背景知识 预处理&#xff08;进行…

什么是Serverless?

Serverless 无服务器&#xff1b;无主机&#xff1b; Serverless &#xff0c;按中文翻译&#xff0c;称为「无服务器」。被认为是新一代的云计算发展方向。 在某些场景可以解读为一种软件系统架构方法&#xff0c;通常称为 Serverless 架构 关于 Serverless 的定义&#xf…

留学Assignment写作怎么注意论证方法?

Assignment的论证方法&#xff0c;对于一篇Assignment而言&#xff0c;学会如何论证&#xff0c;对Assignment的逻辑和内容&#xff0c;有一定的作用。掌握常用的论证方法&#xff0c;了解Assignment要求&#xff0c;在Assignment写作的过程中&#xff0c;学会加以应用&#xf…

VMware 安装、移除Ubuntu系统

目录 前言 安装虚拟机 1. 新建虚拟机 2. 进入向导 3. 选择系统镜像 4. 添加系统设置&#xff0c;用户名主机名密码 <实际没啥用...在系统安装过程中才设置的> 5. 设置虚拟机名称&#xff0c;存放位置 6. 磁盘容量 7. 设置虚拟机硬件配置 8. 自定义硬件 9. 开机…

如何实现jwt鉴权机制?

一、是什么 JWT&#xff08;JSON Web Token&#xff09;&#xff0c;本质就是一个字符串书写规范&#xff0c;如下图&#xff0c;作用是用来在用户和服务器之间传递安全可靠的信息 在目前前后端分离的开发过程中&#xff0c;使用token鉴权机制用于身份验证是最常见的方案&…

Unity 发布安卓包的配置

unity版本是&#xff1a;unity5.6.7&#xff0c;主要是我现在工作中只会在一些工业软件中会用到3d部分&#xff0c;所以版本低了一些&#xff0c;感觉低版本打开unity的速度反而更快一些。发布这个帖子主要目的是 Android SDK 可选项太多了&#xff0c;不熟悉的话&#xff0c;根…

数据技术篇之数据同步

第3章 数据同步 1.数据同步基础 直连同步 &#xff08;1&#xff09;什么是直连同步&#xff1f;直连同步是指通过定义好的规范接口 API 和基于动态链接库的方式直接连接业务库&#xff0c;如 ODBC/JDBC 等规定了统 一规范的标准接口&#xff0c;不同的数据库基于这套标准接口…

gnulib源码安装

接上文《autoconf-archive源码安装》&#xff0c; 链接如下&#xff1a; autoconf-archive源码安装_蓝天居士的博客-CSDN博客 上篇文章在构建autoconf-archive的时候&#xff0c;第一步引导构建就出现了错误&#xff0c;如下所示&#xff1a; $ ./bootstrap.sh ./bootstrap…

SSM+Mysql实现的大学校园兼职系统(功能包含注册登录,发布兼职、个人中心、论坛交流、系统公告、查看兼职信息、查看用户信息、私聊等)

博客目录SSMMysql实现的大学校园兼职系统实现功能截图系统功能使用技术代码完整源码SSMMysql实现的大学校园兼职系统 本系统是一个在线的大学校园兼职系统&#xff0c;商家可以在上面发布自己的兼职&#xff0c;学生可以根据自己的需要&#xff0c;联系兼职&#xff0c;给学生…

JavaScript 中如何实现并发控制?

一、并发控制简介 在日常开发过程中&#xff0c;你可能会遇到并发控制的场景&#xff0c;比如控制请求并发数。那么在 JavaScript 中如何实现并发控制呢&#xff1f;在回答这个问题之前&#xff0c;我们来简单介绍一下并发控制。 假设有 6 个待办任务要执行&#xff0c;而我们…

Kubernetes HPA 动态弹性扩缩容

1.HPA 1.1HPA介绍 1.在Kubernetes中&#xff0c;HPA自动更新工作负载资源&#xff08;例如&#xff1a;Deployment或者StatefulSet&#xff09;&#xff0c;目的是自动扩缩工作负载以满足需求&#xff0c;水平扩缩意味着对增加的负载的响应是部署更多的 Pod&#xff0c;与垂直…

算法工程师深度解构ChatGPT技术

引言 | 本栏目特邀腾讯知名语言文本项目算法工程师冉昱、薛晨&#xff0c;用专业视野带你由浅入深了解ChatGPT技术全貌。它经历了什么训练过程&#xff1f;成功关键技术是什么&#xff1f;将如何带动行业的变革&#xff1f;开发者如何借鉴ChatGPT思路和技术&#xff0c;投入到日…

西门子PLC S7-1500产生精确时间戳及各种数据处理的方法

目录 1、完整程序 2、将时钟转换成整型数 3、获取相对时间 4、转成微秒&#xff08;μs&#xff09;&#xff0c;并转成32位无符号整数 5、翻转的问题 6、有时间戳采集时的对时机制 在数据采集时&#xff0c;精准的相对时间是非常重要的。尤其是高速采集时&#xff0c;上位…