Linux进程控制——Linux进程终止
前言:前面了解完前面的Linux进程基础概念后,我们算是解决了Linux进程中的一大麻烦,现在我们准备更深入的了解Linux进程——Linux进程控制!
我们主要介绍的Linux进程控制内容包括:进程终止,进程等待与替换,进程程序替换!

本篇主要内容:
重识进程创建
进程退出场景
错误码和退出码

进程终止
- 1. 重识进程创建
- 1.1 fork函数
- 1.2 写时拷贝
- 1.3 fork创建进程与进程终止
- 2. 进程终止
- 2.1 main的退出码
- 2.2 C语言的错误码
- 2.3 进程异常终止
- 3. 总结拓展
- 拓展:exit与_exit的区别
- 总结
1. 重识进程创建
1.1 fork函数
在我们之前提到过,创建进程使用的是fork函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。
#include <unistd.h>pid_t fork(void);// 返回值:自进程中返回0,父进程返回子进程id,出错返回-1
进程调用fork,当控制转移到内核中的fork代码后,内核做:
- 分配新的内存块和内核数据结构给子进程
- 将父进程部分数据结构内容拷贝至子进程
- 添加子进程到系统进程列表当中
- fork返回,开始调度器调度
fork函数返回值:
- 子进程返回0,
- 父进程返回的是子进程的pid
这些我们在之前都提到过,我们复习一下,今天我们重点要讲的是fork的写时拷贝
1.2 写时拷贝
通常,父子代码共享,父子再不写入时,数据也是共享的,当任意一方试图写入,便以写时拷贝的方式各自一份副本。

当父进程形成子进程之后,子进程写入,发生写时拷贝,重新申请空间,进行拷贝,修改页表(OS)
但是,我们怎么知道发生了写时拷贝呢?写时拷贝的内容都是由操作系统来完成的
- 其实父进程创建子进程的时候首先将自己的读写权限,改成只读,然后再创建子进程,此时是操作系统在做,用户并不知道,而且用户可能会对某一数据进行写入,这时页表转换就会出现问题,操作系统就会介入,就触发了我们重新申请内存拷贝内容的策略机制
1.3 fork创建进程与进程终止
接下来我们看一下这段代码:
#include<stdio.h>#include<unistd.h>#include<stdlib.h>#define N 10typedef void (*callback_t)(); // 函数指针void Worker(){int cnt = 10;while(cnt){printf("i am child process, pid: %d, ppid: %d, cnt: %d\n", getpid(), getppid(), cnt);sleep(1);cnt--;}}void createSubProcess(int n, callback_t cb){int i = 0;for(i = 0; i < n; i++){sleep(1);pid_t id = fork();if(id == 0){printf("create child process success: %d\n", i);// childcb(); exit(0);}}}int main(){createSubProcess(N, Worker);// 只有父进程走到这里 sleep(100);return 0;}
而代码中的exit函数可以让进程终止

这段代码涵盖了fork创建进程与进程终止,让我们来执行以下
fork创建进程与进程的终止
下面将让我们真正来了解进程终止!
2. 进程终止
进程退出场景:
- 代码运行完毕,结果正确
- 代码运行完毕,结果不正确
- 代码异常终止
前面二者都是正常退出,而最后则是异常退出
2.1 main的退出码
我们之前写代码中,main函数只能return 0吗?答案是肯定不是!
在多进程环境中,我们创建子进程的目的就是协助父进程办事,但是父进程怎么知道子进程把事情办得怎么样?所以父进程要知道子进程办的怎么样,就有了退出码,而main函数的返回值,就是进程的退出码!
返回 0 就表示成功,其他数字就表示进程失败的原因,每个不同的数字代表不同的原因!
我们可以通过函数来直接查看每个数字代表的意义:strerror

它可以返回描述错误码的字符串
#include<stdio.h>
#include<string.h>int main()
{for(int i = 0; i < 200; i++){printf("%d: %s\n", i, strerror(i));}return 0;
}

退出码 0 正好对应的是成功!

当我们134位置处时,发现已经没有错误信息了。
注意:错误码我们可以自己自定义!
main函数的退出码是可以被父进程获取的,用来判断子进程的运行结果
我们可以直接用指令查看进程的退出码:
指令:echo $?
int main()
{return 31;
}
我们在执行完,这段代码后,再用指令查看退出码

我们可以发现指令:echo $?返回的是上一个进程的错误码
2.2 C语言的错误码
错误码和退出码:
- 错误码通常是衡量一个库函数或者是一个系统调用一个函数的调用情况
- 退出码通常是一个进程退出的时候,他的退出结果
- 二者都是当失败的时候,用来衡量函数、进程出错是的出错详细原因
我们用代码来测试一下:
#include<stdio.h>
#include<errno.h>int main(){// errno 可以返回最近一次错误的错误码int ret = 0;printf("before: %d\n", errno);FILE *fp = fopen("csdn.txt", "r");if(fp == NULL){printf("after: %d, error string: %s\n", errno, strerror(errno)); ret = errno;}return ret;}


一旦出现错误,错误码errno就会被系统自动赋值
可以通过错误码来判断代码运行的情况
2.3 进程异常终止
当我们的代码出异常了,也就是进程异常终止了,退出码还有意义吗?
// 当我们在运行这样的代码时int a = 100;
a /= 0;
......
int *p = NULL;
*p = 100;
......
第一种情况: Floating point exception
第二种情况: Segmentation fault
当然不止这两个情况,但是它们都会让程序进程异常终止!
其实一旦程序出现了异常,操作系统就是通过信号的方式来杀掉这个进程!

而我们的前面两种情况正好对应了kill -8 和 kill -11,
我们来试试,通过使用信号能不能还原之前这几种错误情况
while(1)
{printf("i am a process, pid: %d\n", getpid());sleep(1);
}
通过信号终止进程
进程出异常本质是收到了对应的信号,因此一个进程是否出异常,我们只要看有没有收到信号即可
3. 总结拓展
拓展:exit与_exit的区别
在之前讲到正常退出时,我们有3种情况。
正常终止
- 从main返回
- 调用exit
- _exit
而exit与_exit两个有什么区别和联系呢?


首先他们二者都可以让进程终止,并且使用方法也一样,那他们到底有什么区别呢?我们用代码来一探究竟!
//代码一:
int main()
{printf("Hello");exit(0);
}......
//代码二:
int main()
{printf("Hello");_exit(0);
}
代码一:

代码二:

为什么会出现这种情况呢?
exit最后也会调用exit, 但在调用exit之前,还做了其他工作:
- 执行用户通过 atexit或on_exit定义的清理函数。
- 关闭所有打开的流,所有的缓存数据均被写入
- 调用_exit

printf打印如果不使用\n换行的话,数据会被存储到缓冲区里,,exit函数会帮助我们
刷新缓冲区的数据,然而_exit函数不会。因为exit函数在调用exit之前将所有缓存数据都写入了,所以在终止进程时,会将数据打印在屏幕上!
总结
进程终止相对于其他的进程控制来说,是很好理解的。我们主要介绍了进程终止,在明白错误码和退出码之后,相信能理解父进程是怎么得到子进程信息的。让我们期待下一节——进程等待与替换!
谢谢大家支持本篇到这里就结束了

相关文章:
Linux进程控制——Linux进程终止
前言:前面了解完前面的Linux进程基础概念后,我们算是解决了Linux进程中的一大麻烦,现在我们准备更深入的了解Linux进程——Linux进程控制! 我们主要介绍的Linux进程控制内容包括:进程终止,进程等待与替换&a…...
利用IP地址查询解决被“薅羊毛”的方法
在互联网时代,随着各种网络诈骗手段的不断更新和演变,“薅羊毛”成为了一种常见的网络犯罪行为。其中,利用查询IP地址进行欺诈活动已经成为一种普遍的手段。当个人或组织的IP地址被不法分子查询后,可能会面临虚假注册、盗取个人信…...
Tomcat7+ 弱口令 后台getshell漏洞
1 漏洞背景 Tomcat 是一个流行的开源Web应用服务器,用于部署和运行Java Web应用程序。Tomcat 7 版本中存在一个安全隐患,即默认的管理员密码可能较弱或者未被修改,攻击者可以利用这一漏洞登录到Tomcat的管理后台,并上传恶意的WAR…...
香港虚拟主机哪里可以试用?用于企业建站的
香港虚拟主机适合个人、企业建站,包括外贸企业网站、个人博客网站、中小企业官网等,那么作为新手不知道哪家香港虚拟主机好用的时候,该如何找到可以试用的香港虚拟主机呢? 香港虚拟主机也称作香港空间、香港虚拟空间,…...
C# 集合(四) —— Set类
总目录 C# 语法总目录 集合四 Set 1. Set 1. Set 有 HashSet 和 SortedSet, 它们都不包含重复元素忽略添加重复值的请求无法根据位置访问元素使用Contains方法均使用散列查找,所以速度快 SortedSet 按照一定顺序保存元素,使用红黑树实现&a…...
C#实现多线程的几种方式
前言 多线程是C#中一个重要的概念,多线程指的是在同一进程中同时运行多个线程的机制。多线程适用于需要提高系统并发性、吞吐量和响应速度的场景,可以充分利用多核处理器和系统资源,提高应用程序的性能和效率。 多线程常用场景 CPU 密集型任务…...
C语言—控制语句
控制语句就是用来实现对流程的选择、循环、转向和返回等控制行为。 分支语句 if语句 基本结构 if(表达式) { 语句块1; } else { 语句块2; } 执行顺序: 如果表达式判断成立(即表达式为真),则执行语句块…...
三. TensorRT基础入门-ONNX注册算子的方法
目录 前言0. 简述1. 执行一下我们的python程序2.转换swin-tiny时候出现的不兼容op的例子3. 当出现导出onnx不成功的时候,我们需要考虑的事情4. unsupported asinh算子5. unsupported deformable conv算子总结参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战…...
01、什么是ip、协议、端口号知道吗?计算机网络通信的组成是什么?
声明:本教程不收取任何费用,欢迎转载,尊重作者劳动成果,不得用于商业用途,侵权必究!!! 目录 前言 计算机网络 网络ip地址 网络协议 网络端口号 前言 最近有个项目要用到相关文章…...
答题套路2 阅读理解 说明文某个词是否能去掉
观点 回答:不能 解词 某个词什么意思需要解释一下 反证法 如果去掉了,会怎么样 总结 使用这个词体现了说明文的科学性,严谨性...
Pytorch图像分类模型模型实时在线验证代码
1.训练并保存自己的模型 保存的模型格式为:XXX.pth torch.save(model, "./weight/last.pth")if best_acc <(validation_acc / len_val):torch.save(model, "./weight/best.pth")2.转化为ONNX格式 2.1环境安装(window10&#x…...
Java高并发场景(银行转账问题)
最近面试问到了银行转账的高并发问题,回答的不是很理想,小编整理了下,题目大概如下: 有一张银行账号表(银行账号字段、金额字段),A账号要给B账号转账,A扣款,B收款&#x…...
TypeScript 工具类型
这些工具类型是 TypeScript 提供的强大功能,用于操作和转换类型。下面是每个工具类型的简要说明和示例: 1、Record let value: Record<string, any> { name: "", age: 0, desc: [] }; let value2: { [key: string]: any } { name: &…...
[Kotlin]创建一个私有包并使用
1.创建Kotlin测试项目 在Android Studio或其他IDE中选择“Create New Project”。选择Kotlin和Gradle作为项目类型和构建系统。指定项目名称和位置,完成设置。 2.创建Android Library模块 官方文档:创建 Android 库 | Android Studio | Android De…...
鸿蒙应用开发者高级认证指南及参考资料整理(含详细参考答案)
如何报名鸿蒙应用开发者高级认证 报名链接:点击这里进行报名。报名步骤: 点击上述链接进入报名页面。选择“立即报名”。在课程内容中找到“HarmonyOS应用开发者高级认证”,点击进入。点击“参加考试”,随后即可开始考试。考试注意事项 实名认证:考试前,请务必完成实名认…...
数据匿名化技术
不同的数据匿名化技术可用于多种行业,旨在从数据流中获取有用的见解,同时确保满足数据保护标准和法规的合规要求。 数据脱敏(Data Masking) 数据脱敏,又称数据漂白、数据去隐私化或数据变形,指的是对数据集…...
HTML学习笔记汇总
整理一些常见问题的Links,不定期更新。 Html生成自定义函数的图形(2024/5/10)-CSDN博客 HTML中插入图片(2024/5/10)-CSDN博客 Html给网页加icon图标_html icon-CSDN博客...
初始JSVMP
1.初始JSVMP JSVMP是"JavaScript Virtual Machine Protection"的缩写,是一种前端代码虚拟化保护技术。它的核心思想是在JavaScript代码保护过程中引入代码虚拟化,将目标代码转换成自定义的字节码,这些字节码只有特殊的解释器才能识…...
【机器学习数据可视化-04】Pyecharts数据可视化宝典
一、引言 在大数据和信息爆炸的时代,数据可视化成为了信息传递和展示的关键手段。通过直观的图表和图形,我们能够更好地理解数据,挖掘其背后的信息。Pyecharts,作为一款基于Python的数据可视化库,凭借其丰富的图表类型…...
通过 Java 操作 redis -- zset 有序集合基本命令
目录 使用命令 zadd,zrange 使用命令 zcard 使用命令 zrem 使用命令 zscore 使用命令 zrank 关于 redis zset 有序集合类型的相关命令推荐看Redis - Zset 有序集合 要想通过 Java 操作 redis,首先要连接上 redis 服务器,推荐看通过 Jav…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
