【hello Linux】进程概念(下)

news/2024/11/28 13:36:31/

目录

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.ppmy.cn/news/46316.html

相关文章

为什么FTP会随着时间的过去而变慢?

有人问&#xff1a;我在XP上有FZ客户端3.5.3&#xff0c;在Vista上有0.9.41服务器。通过已经很慢的连接传输大文件时&#xff0c;我注意到速度开始时约为40kb / s&#xff0c;但逐渐趋于稳定&#xff0c;约为20kb / s&#xff0c;并保持这种状态。如果我退出客户端并重新启动它…

批处理脚本用法总结

目录 一、常用命令二、基本语法1. rem 和 ::2. echo 和 3. pause4. errorlevel5. title6. color7. goto 和 :8. find9. start10. assoc 和 ftype11. pushd 和 popd12. call13. if 三、常用特殊符号1. 2. %3. >4. >> 四、常见用法1. 设置临时环境变量2. 启动CMD执行命令…

systemctl 命令设置开机自启动失败

1.案例现象 我在 3 月 31日的时候发表了一篇《shell 脚本之一键部署安装 Nginx 》&#xff0c;介绍了如何通过 shell 脚本一键安装 Nginx 我脚本中执行了 Nginx 开机自启动的命令&#xff0c;当我使用 systemctl status nginx 命令复核的时候&#xff0c;我发现 Nginx 服务设…

redis学习

Redis 1.安装 vi /etc/sysconfig/network-scripts/ifcfg-ens33 #修改网络安装gcc依赖 yum install -y gcc tclcd redis-6.2.11 make && make installcp redis.conf.bck redis.conf #修改redis.conf bind 0.0.0.0 daemonize yes requirepass 123456cd /usr/local/src…

Attention注意力机制

加粗样式通俗理解&#xff1a;你会注意什么&#xff1f; 对于一个模型而言&#xff08;CNN&#xff0c;LSTM&#xff09;&#xff0c;模型本身很难决定什么重要什么不重要&#xff0c;因此注意力机制诞生了。 注意力机制&#xff1a;我们会把焦点聚焦在比较重要的事务上 怎么…

一本通 3.4.6 拓扑排序

1352&#xff1a;【例4-13】奖金 【题目描述】 由于无敌的凡凡在2005年世界英俊帅气男总决选中胜出&#xff0c;Yali Company总经理Mr.Z心情好&#xff0c;决定给每位员工发奖金。公司决定以每个人本年在公司的贡献为标准来计算他们得到奖金的多少。 于是Mr.Z下令召开m方会谈…

Markdown 使用 Emoji 表情 MD格式小表情大全

文章目录 Markdown 使用 Emoji 表情 && MD格式小表情大全# 复制和粘贴表情符号# 使用表情符号简码MD格式小表情大全结语Markdown 使用 Emoji 表情 && MD格式小表情大全 有两种方法可以将表情符号添加到Markdown文件中:将表情符号复制并粘贴到Markdown格式的文…

1.4 Docker Swarm-详细介绍

Docker Swarm 是 Docker 官方推出的容器编排工具&#xff0c;用于管理 Docker 容器集群。Docker Swarm 的主要功能包括容器的部署、扩容、缩容、更新等。本文将详细介绍 Docker Swarm 的相关概念、架构、部署和使用方法。 一、Docker Swarm 概述 Docker Swarm 是 Docker 官方…