【hello Linux】进程概念(下)

news2024/9/24 0:34:06

目录

1. 通过系统调用创建进程—fork

1.1 通过fork创建进程:

1.2 如何不退出 vim 直接执行命令呢?

3. fork创建进程的本质

4. 父子进程的分流:

 2. 进程状态

 3. 信号

3.1 显示全部信号

3.1 停止进程

3.2 继续进程

3.3 杀死进程

 后台进程

 4. 僵尸进程与孤儿进程

4.1 僵尸进程

4.2 孤儿进程


 Linux🌷

1. 通过系统调用创建进程—fork

1.1 通过fork创建进程:

经过运行,确实证明了它们是父子关系。

那父进程是由哪个进程创建的呢?

经过查看它是由 bash 创建的。

1.2 如何不退出 vim 直接执行命令呢?

1. 在 vim 下使用man手册查看fork的用法

2. 在vim下编译.c文件

3. 在vim下运行程序

上述命令执行完后,我们按q直接便可以进入vim的命令模式

3. fork创建进程的本质

在操作系统中,创建进程有多种方式:

1. 在shell中执行各种命令;

2. 使用fork()系统调用;

其实在操作系统角度,上述两种创建进程的方式是没有差别的!!!

fork 创建进程的本质

fork会创建进程那就意味着,操作系统中多了一个进程,也就是说多了:与进程相关的内核的数据结构(task_struct) + 进程的代码和数据,那它们是怎么来的呢?

  1. task_struct是以父进程为模板,由操作系统来进行初始化获得的;
  2. 进程的代码和数据在默认情况下,会继承父进程的全部代码和数据;
  3. fork之后子进程和父进程代码是共享的,内存中只有一份代码;
  4. 子进程拥有全部的代码,只是因为程序一直往后执行,所以可以看到子进程执行fork后续的代码,但若修改子进程的PC,子进程也可以执行fork之前的代码;
  5. 在不考虑修改的情况下,父子进程数据也是共享的,但若修改时,则是通过“写时拷贝”完成的,以此来实现进程的独立性。

写时拷贝

原本内存中,父子进程共享数据,但当父(子)进程想要修改数据时,那边会在内存中拷贝一份需要修改的数据,然后供此进程使用。

我们创建子进程就是为了让和父进程干一样的事吗?

其实我们还可以使用 if else 对 fork() 的返回值进行判断,根据返回值的不同,进行分流,让它们执

行不同的事情。

4. 父子进程的分流:

fork的返回值: 

失败:<0;

成功:给父进程返回子进程的pid;

           给子进程返回0;

下述代码是一个父子进程分流的样例:

如何理解fork会有两个返回值呢?

其实fork是一个函数,首先执行fork内部的核心功能(创建子进程),完了之后便执行return 返回值,

在return之前,子进程已经创建完毕,父子进程各自执行return,return之后的返回值也是数据,这

是便发生了“写时拷贝”,产生了不同的返回值。

 fork之后,其实父子进程谁先运行,这是不确定的,是由调度器(CPU)来进行调度的。

 2. 进程状态

进程是有状态信息的。其本质是一种分类,是为了方便OS快速判断进程,完成特定的功能。

进程的状态信息存在task_struct中。

在内核源代码中进程的状态有如下定义:

/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
}; 

R:运行状态

 注意:

运行状态并不意味着进程一定在运行中,它表明进程要么是在运行中,要么在运行队列里。

操作系统会对运行队列中的task_struct进行调度,每次调度相隔时间很短,我们察觉不到。

S:可中断睡眠 / 浅度睡眠

D:不可中断睡眠 / 深度睡眠

当进程需要等待除了CPU外的其他资源时,便会陷入睡眠状态,例如:磁盘、网卡、显示器

等资源;

我们把,从运行状态的task_struct从run_queue,放到等待队列中,就叫做挂起等待,也称为

阻塞;

从等待队列,放到运行队列,被CPU调度就叫做唤醒进程。

深度睡眠:D

当进程需要磁盘资源时,对磁盘进行申请,磁盘的动作是很慢的,CPU的动作是很快的;

此时内存资源极度缺乏,OS看见此进程在睡眠(其实在申请磁盘资源),便杀死此进程,腾出资

源,这时此进程便进入深度睡眠状态;

在此状态,该进程是不可被 ctrl c 退出的,也不能 kill -9 pid 杀死该进程。

最简单的方式便是重启shell;

另一种便是修改内核,将进程状态由D改为其他状态,然后使用kill ,一般很少会遇见。

 S:可中断睡眠 / 浅度睡眠

我们很疑惑:进程不是一直在运行吗?为什么还是处于浅度睡眠态呢?

这个程序是将内容输出到显示器上的,显示器是一个外设,对于CPU来说速度特别慢;

进程其实是一直处在R与S状态的切换中的。

而R:运行状态演示的那个代码没有输出操作,不用等待IO因此处于R态;

在S状态,按 ctrl c 可退出进程的运行;

 T:停止状态

彻底停止,什么都不做,不同于S,S只是睡眠,比如sleep(1),更新:1秒最后会为0;

t:追踪状态

因为追踪而进行定位,它的典型应用为:F9打断点后,查看一些信息;

X:死亡状态

进程死亡便要回收:进程资源 = 进程相关的内核数据结构 + 进程的代码和数据

Z:僵尸状态

有僵尸状态是为了辨别进程退出死亡的原因!也就是进程推出的信息,它也是一种数据,是存在

task_struct中的

3. 信号

3.1 显示全部信号

kill -l

 在信号里面有三个我们常用的:

3.1 停止进程

kill -19 pid

3.2 继续进程

kill -18 pid

3.3 杀死进程

kill -9 pid

 后台进程

 后台进程:可以在运行时输命令,无法ctrl c杀死,只能kill -9 pid杀死 

将一个进程在后台运行:

//原本正常运行程序
./test

//后台运行
./test &

将后台进程提到前台:

后台运行是可以输入命令的
直接在正在运行进程的会话中输入fg命令

4. 僵尸进程与孤儿进程

4.1 僵尸进程

僵死状态( Zombies )是一个比较特殊的状态。
当子进程退出并且父进程(使用 wait() 系统调用 , 后面讲)
没有读取到子进程退出的返回代码时就会产生僵死 ( ) 进程;
僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入 Z 状态

也就是说:

当父进程一直存在,子进程被杀,但子进程的资源没有被回收,那么子进程便会变为僵尸状态;

当一个进程处于僵尸状态时,kill 9也无法杀死;

 杀死子进程查看发现子进程变成僵尸状态。

僵尸进程的危害:

进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任
务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z 状态?
是的
维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在 task_struct(PCB)
中,换句话说,Z 状态一直不退出, PCB 一直都要维护?是的
那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因
为数据结构对象本身就要占用内存,想向C 中定义一个结构体变量(对象),是要在内存的
某个位置进行开辟空间!
内存泄漏 ? 是的!
如何避免?后面讲

4.2 孤儿进程

当父进程先退出,那么父进程创建的子进程便会称为孤儿进程,该进程会被1号进程领养;

1号进程为操作系统;

杀死父进程,查看发现子进程变为孤儿,被1号进程领养,1号进程为操作系统;

 坚持打卡!

😃

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

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

相关文章

在pycharm2020上部署配置AutoGPT4.0,保姆级教程

前期环境及软件准备&#xff1a; 1&#xff09;pycharm版本2020及以上 2&#xff09;python版本3.10及以上 3&#xff09;pip版本20及以上&#xff08;新一点的版本&#xff09; 4&#xff09;安装git&#xff0c;无版本要求 正式开工 具体配置步骤如下&#xff1a; 1.AUTOGP…

【UE 粒子系统】使用GPU渲染粒子

GPU Sprite 是虚幻引擎4中可用的粒子类型之一。这些粒子首先在CPU上生成&#xff0c;但之后完全由显卡处理和计算。这样做的好处是&#xff0c;由于GPU负责处理计算&#xff0c;因此可以同时处理成千上万的粒子&#xff0c;从而实现更密集和更细节化的粒子系统。 在上一篇博客&…

PPC380AE102 HIEE300885R0102现代自动化技术

PPC380AE102 HIEE300885R0102现代自动化技术 ​ 交流伺服电机驱动器示例 目前世界人口已经达到了78亿&#xff0c;并且还在不断增加&#xff0c;预计到2050年将达到100亿。日益增长的人口既有对衣服&#xff0c;食物等基本必需品的需求&#xff0c;对舒适、安全生活的追求也不断…

C++并发数据结构设计

关键词&#xff1a;原子操作&#xff0c;无锁设计 引入问题-> 为什么需要原子操作-> 原子操作实现以及原理-> c原子操作接口-> c基于原子操作的数据结构设计-> 原子操作 什么是原子操作 所谓原子操作,就是"不可中断的一个或一系列操作" 。 2…

列表和元组(上)——“Python”

各位CSDN的uu们你们好呀&#xff0c;今天小雅兰的内容是Python中的列表&#xff0c;下面&#xff0c;让我们进入列表的世界吧 列表是什么, 元组是什么 创建列表 访问下标 切片操作 遍历列表元素 列表是什么, 元组是什么 编程中, 经常需要使用变量, 来保存/表示数据. 如果…

Swift 注释和文档

今天&#xff0c;我知道我写是什么&#xff0c;上帝和我知道 明天&#xff0c;我知道这个代码什么意思&#xff0c; 后天&#xff0c;我知道这是我写的代码&#xff0c; 一周后&#xff0c;这TM谁写的代码&#xff0c;此时只有上帝才知道啥意思 论代码注释的重要性。 普通…

React Native 混合ios android开发 及常用框架

英文文档&#xff1a;Setting up the development environment React Native 中文文档&#xff1a;集成到现有原生应用 React Native 中文网 ios 在集成过程中&#xff0c;需要修改package.json 和 Podfile&#xff0c;按文档中的内容&#xff0c;如果pod install过不了的…

用Kotlin 一步步抄作业写一个Redux

前言 我抄的作业 完全理解 redux&#xff08;从零实现一个 redux&#xff09; Issue #22 brickspert/blog GitHub 一.架构设计模式 1. mvc>mvp>mvvm->mvi 2.Redux实现类Mvi Android Mvi 与Redux对比&#xff0c;思想一致&#xff0c;单向数据流&#xff0c;单…

最优控制 3:最优控制理论中的极小值原理与动态规划

最优控制 3&#xff1a;使用极小值原理求解最优控制问题 引言极小值原理 t f t_f tf​ 固定的情况 t f t_f tf​ 自由的情况 动态规划连续系统 HJB 方程的推导 引言 经典变分法是一种特别强大的工具&#xff0c;但是它要求控制量必须可导且无界&#xff0c;这在很多问题中都是…

pandas读取列数不同的CSV文件

使用pandas读取每行不同列的CSV文件 对于序列模型而言&#xff0c;每条数据的大小都不一定相等&#xff0c;但对于一般的神经网络要求输入大小相等。目前的一种方法是选取当前数据集中最大长度的数据作为基准数据大小&#xff0c;其余的数据末尾补零来规范整个数据集每条数据的…

计算机:理解操作系统:内存篇(下)

内存 1. 指针与引用2. 进程的内存模型3. 幻象大师---操作系统4. 总结 本篇是 关于计算机内存最后一篇文章 什么是内存 C/C内存模型 堆区与栈区的本质 Java、Python等内存模型 Java内存模型 Jave中的堆区与栈区是如何实现的 Python内存模型 指针与引用 进程的内存模型 幻想大师-…

css tooltip (web.dev)

目录 版权介绍tool-tip在上居中动画效果宽度边界 tool-tip::after范围锥形渐变-webkit-mask尖角怎么来的? 附录完整代码 版权 本文为原创, 遵循 CC 4.0 BY-SA 版权协议, 转载需注明出处: https://blog.csdn.net/big_cheng/article/details/130262213. 介绍 https://web.dev…

【周末闲谈】AI作图,你真的了解它吗?

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️周末闲谈】 系列目录 ✨第一周 二进制VS三进制 ✨第二周 文心一言&#xff0c;模仿还是超越&#xff1f; ✨第二周 畅想AR 文章目录 系列目录前言AI绘画&#x1f916;&#x1f916;&#x1f916;工作…

[C++]:万字超详细讲解多态以及多态的实现原理(面试的必考的c++考点)

文章目录 前言一、多态的定义及实现1.多态的构成条件2.c11的override和final3.重载&#xff0c;重写&#xff0c;重定义的比较4.抽象类5.多态的原理6.多继承中的虚函数表7.动态绑定和静态绑定总结 前言 多态的概念&#xff1a; 多态的概念&#xff1a;通俗来说&#xff0c;就是…

【Linux】使用systemd设置开机自启动命令

目录 1 使用使用systemd实现开机自动运行命令1.1 新建一个.service文件1.2 编写.service文件1.2.1 [Unit]1.2.2 [Service]1.2.3 [Install] 1.3 启动服务并设置自启动 2 编写Systemd服务文件的要点2.1 Systemd服务文件的位置2.2 Systemd服务文件的格式2.3 Systemd服务文件的基本…

【基础】Kafka -- 基础架构及核心概念

Kafka -- 基础架构及核心概念 初识 KafkaKafka 基本架构Kafka 主题与分区主题与分区分区副本机制 Replica高水位 HW 生产者生产者客户端必要的参数配置消息的发送序列化分区器生产者拦截器 原理分析重要的生产者参数 消费者消费者与消费者组消费者客户端必要的参数配置订阅主题…

MySQL 按关键字进行截取

一、问题背景 取MySQL数据表中某个字段中的IP信息。 如&#xff1a;t_log 表中的 user_ip 字段值为 {“username”:“miracle”,“ip”:“110.230.128.186”}&#xff0c;取出IP信息 110.230.128.186。 建表和初始化SQL语句&#xff0c;如下&#xff1a; SET NAMES utf8mb4…

GORM操作mysql数据库

对象就是程序的数据结构&#xff0c;关系是数据库。就是将程序的数据结构与数据库表对应起来。 在GORM是Go语言的ORM框架&#xff0c;将go的数据结构转化为数据库表&#xff0c;例如将结构体转化为数据库表。 引入gorm框架 远程下载gorm框架 go get -u gorm.io/driver/mysq…

HTTP中的Content-type详解

Content-Type Content-Type&#xff08;MediaType&#xff09;&#xff0c;即是Internet Media Type&#xff0c;互联网媒体类型&#xff0c;也叫做MIME类型。在互联网中有成百上千中不同的数据类型&#xff0c;HTTP在传输数据对象时会为他们打上称为MIME的数据格式标签&#x…

关于java.io的学习记录(写入文本)

可以通过字节流&#xff08;FileOutputStream&#xff09;、字符流&#xff08;OutputStreamWriter&#xff09;、字符缓冲流&#xff08;BufferedWriter&#xff09;读取文本中的数据。 FileOutputStream写入文本 public void write(){String path "writeTest.txt"…