当前位置: 首页 > news >正文

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 -8kill -11

我们来试试,通过使用信号能不能还原之前这几种错误情况

while(1)
{printf("i am a process, pid: %d\n", getpid());sleep(1);
}

通过信号终止进程

进程出异常本质是收到了对应的信号,因此一个进程是否出异常,我们只要看有没有收到信号即可


3. 总结拓展

拓展:exit与_exit的区别

在之前讲到正常退出时,我们有3种情况。

正常终止

    1. 从main返回
    1. 调用exit
    1. _exit

而exit与_exit两个有什么区别和联系呢?
在这里插入图片描述
在这里插入图片描述

首先他们二者都可以让进程终止,并且使用方法也一样,那他们到底有什么区别呢?我们用代码来一探究竟!

//代码一:
int main()
{printf("Hello");exit(0); 
}......
//代码二:
int main()
{printf("Hello");_exit(0); 
}

代码一:
在这里插入图片描述
代码二:
在这里插入图片描述
为什么会出现这种情况呢?

exit最后也会调用exit, 但在调用exit之前,还做了其他工作:

    1. 执行用户通过 atexit或on_exit定义的清理函数。
    1. 关闭所有打开的流,所有的缓存数据均被写入
    1. 调用_exit

在这里插入图片描述

printf打印如果不使用\n换行的话,数据会被存储到缓冲区里,,exit函数会帮助我们
刷新缓冲区的数据,然而_exit函数不会。因为exit函数在调用exit之前将所有缓存数据都写入了,所以在终止进程时,会将数据打印在屏幕上!


总结

进程终止相对于其他的进程控制来说,是很好理解的。我们主要介绍了进程终止,在明白错误码和退出码之后,相信能理解父进程是怎么得到子进程信息的。让我们期待下一节——进程等待与替换!

谢谢大家支持本篇到这里就结束了
在这里插入图片描述

相关文章:

Linux进程控制——Linux进程终止

前言&#xff1a;前面了解完前面的Linux进程基础概念后&#xff0c;我们算是解决了Linux进程中的一大麻烦&#xff0c;现在我们准备更深入的了解Linux进程——Linux进程控制&#xff01; 我们主要介绍的Linux进程控制内容包括&#xff1a;进程终止&#xff0c;进程等待与替换&a…...

利用IP地址查询解决被“薅羊毛”的方法

在互联网时代&#xff0c;随着各种网络诈骗手段的不断更新和演变&#xff0c;“薅羊毛”成为了一种常见的网络犯罪行为。其中&#xff0c;利用查询IP地址进行欺诈活动已经成为一种普遍的手段。当个人或组织的IP地址被不法分子查询后&#xff0c;可能会面临虚假注册、盗取个人信…...

Tomcat7+ 弱口令 后台getshell漏洞

1 漏洞背景 Tomcat 是一个流行的开源Web应用服务器&#xff0c;用于部署和运行Java Web应用程序。Tomcat 7 版本中存在一个安全隐患&#xff0c;即默认的管理员密码可能较弱或者未被修改&#xff0c;攻击者可以利用这一漏洞登录到Tomcat的管理后台&#xff0c;并上传恶意的WAR…...

香港虚拟主机哪里可以试用?用于企业建站的

香港虚拟主机适合个人、企业建站&#xff0c;包括外贸企业网站、个人博客网站、中小企业官网等&#xff0c;那么作为新手不知道哪家香港虚拟主机好用的时候&#xff0c;该如何找到可以试用的香港虚拟主机呢&#xff1f; 香港虚拟主机也称作香港空间、香港虚拟空间&#xff0c;…...

C# 集合(四) —— Set类

总目录 C# 语法总目录 集合四 Set 1. Set 1. Set 有 HashSet 和 SortedSet&#xff0c; 它们都不包含重复元素忽略添加重复值的请求无法根据位置访问元素使用Contains方法均使用散列查找&#xff0c;所以速度快 SortedSet 按照一定顺序保存元素&#xff0c;使用红黑树实现&a…...

C#实现多线程的几种方式

前言 多线程是C#中一个重要的概念&#xff0c;多线程指的是在同一进程中同时运行多个线程的机制。多线程适用于需要提高系统并发性、吞吐量和响应速度的场景&#xff0c;可以充分利用多核处理器和系统资源&#xff0c;提高应用程序的性能和效率。 多线程常用场景 CPU 密集型任务…...

C语言—控制语句

控制语句就是用来实现对流程的选择、循环、转向和返回等控制行为。 分支语句 if语句 基本结构 if(表达式) { 语句块1&#xff1b; } else { 语句块2&#xff1b; } 执行顺序&#xff1a; 如果表达式判断成立&#xff08;即表达式为真&#xff09;&#xff0c;则执行语句块…...

三. TensorRT基础入门-ONNX注册算子的方法

目录 前言0. 简述1. 执行一下我们的python程序2.转换swin-tiny时候出现的不兼容op的例子3. 当出现导出onnx不成功的时候&#xff0c;我们需要考虑的事情4. unsupported asinh算子5. unsupported deformable conv算子总结参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战…...

01、什么是ip、协议、端口号知道吗?计算机网络通信的组成是什么?

声明&#xff1a;本教程不收取任何费用&#xff0c;欢迎转载&#xff0c;尊重作者劳动成果&#xff0c;不得用于商业用途&#xff0c;侵权必究&#xff01;&#xff01;&#xff01; 目录 前言 计算机网络 网络ip地址 网络协议 网络端口号 前言 最近有个项目要用到相关文章…...

答题套路2 阅读理解 说明文某个词是否能去掉

观点 回答&#xff1a;不能 解词 某个词什么意思需要解释一下 反证法 如果去掉了&#xff0c;会怎么样 总结 使用这个词体现了说明文的科学性&#xff0c;严谨性...

Pytorch图像分类模型模型实时在线验证代码

1.训练并保存自己的模型 保存的模型格式为&#xff1a;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环境安装&#xff08;window10&#x…...

Java高并发场景(银行转账问题)

最近面试问到了银行转账的高并发问题&#xff0c;回答的不是很理想&#xff0c;小编整理了下&#xff0c;题目大概如下&#xff1a; 有一张银行账号表&#xff08;银行账号字段、金额字段&#xff09;&#xff0c;A账号要给B账号转账&#xff0c;A扣款&#xff0c;B收款&#x…...

TypeScript 工具类型

这些工具类型是 TypeScript 提供的强大功能&#xff0c;用于操作和转换类型。下面是每个工具类型的简要说明和示例&#xff1a; 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作为项目类型和构建系统。指定项目名称和位置&#xff0c;完成设置。 2.创建Android Library模块 官方文档&#xff1a;创建 Android 库 | Android Studio | Android De…...

鸿蒙应用开发者高级认证指南及参考资料整理(含详细参考答案)

如何报名鸿蒙应用开发者高级认证 报名链接:点击这里进行报名。报名步骤: 点击上述链接进入报名页面。选择“立即报名”。在课程内容中找到“HarmonyOS应用开发者高级认证”,点击进入。点击“参加考试”,随后即可开始考试。考试注意事项 实名认证:考试前,请务必完成实名认…...

数据匿名化技术

不同的数据匿名化技术可用于多种行业&#xff0c;旨在从数据流中获取有用的见解&#xff0c;同时确保满足数据保护标准和法规的合规要求。 数据脱敏&#xff08;Data Masking&#xff09; 数据脱敏&#xff0c;又称数据漂白、数据去隐私化或数据变形&#xff0c;指的是对数据集…...

HTML学习笔记汇总

整理一些常见问题的Links&#xff0c;不定期更新。 Html生成自定义函数的图形&#xff08;2024/5/10&#xff09;-CSDN博客 HTML中插入图片&#xff08;2024/5/10&#xff09;-CSDN博客 Html给网页加icon图标_html icon-CSDN博客...

初始JSVMP

1.初始JSVMP JSVMP是"JavaScript Virtual Machine Protection"的缩写&#xff0c;是一种前端代码虚拟化保护技术。它的核心思想是在JavaScript代码保护过程中引入代码虚拟化&#xff0c;将目标代码转换成自定义的字节码&#xff0c;这些字节码只有特殊的解释器才能识…...

【机器学习数据可视化-04】Pyecharts数据可视化宝典

一、引言 在大数据和信息爆炸的时代&#xff0c;数据可视化成为了信息传递和展示的关键手段。通过直观的图表和图形&#xff0c;我们能够更好地理解数据&#xff0c;挖掘其背后的信息。Pyecharts&#xff0c;作为一款基于Python的数据可视化库&#xff0c;凭借其丰富的图表类型…...

通过 Java 操作 redis -- zset 有序集合基本命令

目录 使用命令 zadd&#xff0c;zrange 使用命令 zcard 使用命令 zrem 使用命令 zscore 使用命令 zrank 关于 redis zset 有序集合类型的相关命令推荐看Redis - Zset 有序集合 要想通过 Java 操作 redis&#xff0c;首先要连接上 redis 服务器&#xff0c;推荐看通过 Jav…...

力扣 516. 最长回文子序列 python AC

动态规划 class Solution:def longestPalindromeSubseq(self, s):size len(s)dp [[0] * size for _ in range(size)]for i in range(size):dp[i][i] 1for i in range(size - 1, -1, -1):for j in range(i 1, size):if s[i] s[j]:dp[i][j] dp[i 1][j - 1] 2else:dp[i][…...

数据库编程

PL/SQL程序 1.PL/SOL程序块 整个PL/SQL块分三部分&#xff1a;声明部分、执行部分、异常处理部分&#xff1b; 示例&#xff1a; declare --变量声明 v_sno varchar2(10) : ‘04001’; v_cno varchar2(10) :‘001’; v_grade number : 90; begin --程序入口 insert…...

(docker)进入容器后如何使用本机gpu

首次创建容器&#xff0c;不能直接使用本机gpu 在系统终端进行如下配置&#xff1a; 1.安装NVIDIA Container Toolkit 进入Nvidia官网Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit 1.15.0 documentation&#xff0c;安装NVIDIA Container Toolkit …...

java基础知识点总结2024版(8万字超详细整理)

java基础知识点总结2024版&#xff08;超详细整理&#xff09; 这里写目录标题 java基础知识点总结2024版&#xff08;超详细整理&#xff09;java语言的特点1.简单性2.面向对象3.分布式4.健壮性5.安全性6.体系结构中立7.可移植性8.解释性9.多线程10.动态性 初识java中的main方…...

vue中使用element的i18n语言转换(保姆式教程-保证能用)

话不多说&#xff0c;先看效果:预览地址: https://sandm00.github.io/i18n-switch/#/ 1、项目中需要使用的插件&#xff0c;vue2或vue3、element、vue-i18n、js-cookie、vuex我是在vue2中使用 npm i element-ui -S npm i js-cookie -S npm i vue-i18n8.28.2 //因为我项目使用…...

01 设计模式--单例模式

1. 单例模式 单例模式有两种实现方式&#xff1a; 1.1 饿汉模式&#xff08;Eager Initialization&#xff09;&#xff1a;在类加载时就创建单例实例&#xff0c;无论是否需要使用该实例。 饿汉模式在类加载时就创建单例实例&#xff0c;无论是否需要使用该实例。 饿汉模式…...

css backdrop-filter 实现背景滤镜

官方给出的定义是&#xff1a;backdrop-filter属性允许您将图形效果&#xff08;如模糊或颜色偏移&#xff09;应用于元素后面的区域。因为它适用于元素后面的所有内容&#xff0c;所以要查看元素或其背景的效果&#xff0c;需要透明或部分透明。 大致分为以下10种&#xff1a…...

AR人脸道具SDK解决方案,实现道具与人脸的自然融合

AR人脸道具SDK解决方案&#xff0c;实现道具与人脸的自然融合美摄科技以其卓越的技术实力和创新能力&#xff0c;为企业带来了全新的AR人脸道具SDK解决方案。这一解决方案将为企业打开全新的市场机会&#xff0c;为用户带来前所未有的互动体验。 颠覆传统&#xff0c;开启AR人…...

Windows安装RabbitMQ教程(附安装包)

需要两个安装包 Erlang 安装包: https://download.csdn.net/download/Brevity6/89274663 (自己从官网下载也可以) RabbitMQ Windows 安装包&#xff1a; https://download.csdn.net/download/Brevity6/89274667 (自己从官网下载也可以) Erlang安装 Erlang安装傻瓜式下一…...

这个问题无人能解,菜鸟勿进

前言 这是陈旧已久的草稿2021-06-23 23:25:12 现在2024-5-12 21:53:46&#xff0c;发布到[逻辑题]专栏中。 一、问题 1.描述&#xff1a; 在我的世界中建个红石电路 2.需求&#xff1a; 五个灯A、B、C、D、E、F 五个开关a、b、c、d、e、f、总开关 3.要求&#xff1a; 总开关…...