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

IO进程线程 (进程)

目录

一、进程

1、概念

1)进程和程序的区别:

2)Linux的调度机制:

3)进程是资源分配的最小单元

2、进程的五态图

3、物理内存\虚拟内存

4、进程的标识符(PID)

5、特殊的进程ID

6、进程的指令 

1)查看系统中的每一个进程(ps -ef)

2)查看CPU、内存使用率及状态(ps -aux)

3)打印进程树(pa -ajx)

 4)动态查看进程状态(top)

​编辑

 5)连用指令grep 查看指定进程的PID

1. ps -ef | grep 进程名

2. ps -aux | grep 进程名

3. ps -ajx | grep 进程名

4. top | grep 进程名

6)查看指定进程的PID(pidof)

7)杀死进程(kill)

7、进程的状态

8、进程函数

1)fork(创建子进程)

1. 子进程

2.连续创建子进程

 3. 父子进程的执行顺序

2)getpid | getppid(获取进程号)

3)exit | _exit(结束进程)

4)wait | waitpid(接收回收子进程资源)

5)vfork(创建子进程)

9、特殊进程

1)僵尸进程

1.僵尸进程指 子进程退出了,但是父进程没有回收子进程资源

2. 僵尸进程无法通过 kill 杀死,因为他已经是死掉的进程了

3. 僵尸进程是有害的,必须回收,因为僵尸进程会占用PCB和CPU资源

4. 回收僵尸进程

2)孤儿进程

3)守护进程(幽灵进程)

4)创建守护进程

作业:

1. 创建一个进程扇

2. 创建一个进程链

3.解析以下程序

4. 实现文件的拷贝,父进程拷贝前一部分,子进程拷贝后一部分


一、进程

进程是指 软件(程序)执行的过程

单核处理:多进程同时处理,实际上是在多个软件(程序)之间快速的来回切换

多核处理:部分多个软件(程序)同时执行

1、概念

进程:进程是程序执行的过程、是资源和调度的独立单元

常用于多个死循环的程序同时执行

1)进程和程序的区别:

程序:程序是静态的,存储在硬盘上的

进程:进程是动态的、存储在内存上,包括创建、调度、消亡的过程

2)Linux的调度机制:

CPU以ms级别的速度在多个进程间来回切换

3)进程是资源分配的最小单元

2、进程的五态图

创建态:申请资源,例如PCB资源,填充控制和使用信息,把进程插入到就绪队列中,等待CPU资源
就绪态:已经获取到所有除CPU以外的所有资源,等待获取CPU资源
运行态:已经获取到CPU资源
阻塞态:遇到阻塞函数(如输入函数)当阻塞解除后,进就绪态
终止态:等待操作系统做善后处理,清楚PCB数据,释放PCB资源

3、物理内存\虚拟内存

4、进程的标识符(PID)

Windows的PID可以通过可以通过任务管理器查看

Linux的PID则需要通过指令 /proc 查看

PID: 进程号,是进程的标识,进程号和标识符一样,是不可重复的,唯一的
PPID:父进程号,是打开当前进程的父进程的PID
PGID:进程组号
SID: 会话号

每打开一个终端就是打开一个会话;

一个会话包含一个前台进程组,以及多个后台进程组;

一个进程组包含多个进程。

5、特殊的进程ID

0 : indel 进程  引导进程  创建 1号 和 2号 进程
1 : init 进程   初始化数据  收养孤儿进程(没有父进程或失去父进程的进程)
2 : kthread 进程  实现进程之间的调度

6、进程的指令 

1)查看系统中的每一个进程(ps -ef)

2)查看CPU、内存使用率及状态(ps -aux)

3)打印进程树(pa -ajx)

 4)动态查看进程状态(top)

 5)连用指令grep 查看指定进程的PID

用管道符 | ,可以将grep 和上述的四个指令连用,实现指定查找。

1. ps -ef | grep 进程名

例:查找进程 a.out 的进程

2. ps -aux | grep 进程名

例:查找进程 a.out 的CPU使用率

3. ps -ajx | grep 进程名

例:查找有关进程 a.out 的进程树

4. top | grep 进程名

例:动态查看 a.out 的进程状态(每3s更新状态) 

6)查看指定进程的PID(pidof)

格式:pidof 进程名例:pidof a.out

7)杀死进程(kill)

kill 可以发送62种信号,其中 1~31 是稳定信号、34~64 是不稳定信号

可以使用指令 kill -l 查看62个信号。

 其中常用的信号:

2)SIGINT  ----- 进程在终端运行时,使用的ctrl c 停止
9)SIGKILL  ---- 结束进程 (立刻结束,不会被阻塞,不会被忽略)
15)SIGTERM  --- 结束进程 (使进程善后结束,会被阻塞,会被忽略,但是更安全) 
18)SIGCONT  --- 继续运行进程
19)SIGSTOP ---- 挂起进程格式:kill -信号编号 进程号(PID)   对单个进程执行killall -信号编号 进程名     对进程名的所有进程执行例:kill -9 123456(进程号(PID)) ---- 关闭 123465 单个进程killall -9 a.out --------------- 关闭 a.out 的所有进程

 此外还有关kill的指令:

kill -l 信号编号 -----  变更信号编号的 信号名称    例:kill -l 11 变更 11 的信号名称
kill -l -----------------------------  查看可用的信号
kill 进程号(PID) 进程号 进程号 ··· ---- 结束多个进程

7、进程的状态

指令 ps -aux 可以查看进程当前的状态

 进程的状态主要有以下几种 可以通过 man ps 查看

D    ------- 不可中断的休眠态
R    ------- 正在运行
S    ------- 可中断的休眠态
T    ------- 停止态,挂起态
t    ------- bug调试状态,当gdb调试bug
X    ------- 死亡态
Z    ------- 僵尸(进程结束,但是资源没有被回收)当进程 为 BSD 格式 或 使用 "stat" 关键字时,可以会额外显示以下字符<    ------- 高优先级(对其他用户不友好)
N    ------- 低优先级(相对的对其他用户友好)
L    ------- 将页面所在内存中
s    ------- 会话领导
l    ------- 多线程
+    ------- 处于前台进程组,运行在前端

8、进程函数

1)fork(创建子进程)

格式:  #include <sys/types.h>#include <unistd.h>pid_t fork(void);
功能:拷贝父进程的资源,创建新进程,返回的进程号是子进程的进程号
返回值:成功: 返回给 父进程 子进程的 PID,返回给 子进程 0失败: 返回-1,跟新errno
1. 子进程

进程是运行在映射的虚拟空间内的,父子进程共用同一个虚拟空间的内核

创建子进程时,会拷贝父进程的所有用户空间(栈、堆、静态)

2.连续创建子进程

总进程数是 2^n 个,子孙进程数是 (2^n) -1

 3. 父子进程的执行顺序

父子进程的执行顺序是不确定的,CPU根据事件轮询机制访问

可以通过sleep间接控制执行顺序(不建议:太过影响程序的运行速度)

4. 写实拷贝

创建子进程时会拷贝父进程资源,只进行访问,父子进程会映射到同一片共用物理内存共用。

如果父子进程中的任意一个的数据发生修改,那么父子进程会分别映射到不同的物理内存。

2)getpid | getppid(获取进程号)

格式:#include <sys/types.h>#include <unistd.h>pid_t getpid(void);      //获取进程id并返回pid_t getppid(void);     //获取父进程id并返回

3)exit | _exit(结束进程)

格式:#include <stdlib.h>void exit(int status);
功能:库函数,退出进程的,刷新缓冲区
参数:int status:退出状态值,把该值返回给父进程默认 EXIT_SUCCESS->0表示正常退出,非0   EXIT_FAILURE=1表示异常1.正常退出子进程exit(EXIT_SUCCESS);  exit(0); 
2.异常退出exit(EXIT_FAILURE);  exit(1); exit(-1);
==========================
格式: #include <unistd.h>void _exit(int status);
功能:系统函数,退出进程的,不可以刷新缓冲区
参数:    int status:退出状态值,把该值返回给父进程默认 EXIT_SUCCESS->0表示正常退出,非0   EXIT_FAILURE=1表示异常
--------------------------------
注意:exit _exit的退出状态值返回给父进程

4)wait | waitpid(接收回收子进程资源)

格式:#include <sys/types.h>#include <sys/wait.h>
pid_t wait(int *wstatus);
功能:阻塞函数,在父进程中接收子进程的退出状态值,回收子进程资源
参数:int *wstatus:该指针指向的内存中存储子进程的退出状态值不接收写NULL,不接受子进程的退出状态值
返回值:成功返回接受子进程的进程id失败返-1,跟新errno
==============================
1.可以使用一下的宏函数转换后的退出状态值WEXITSTATUS(wstatus)
#define __WEXITSTATUS(status)   (((status) & 0xff00) >> 8)
2.手动转换退出状态值status >>8 &0xff& 0xff 的作用 取出 -----> 需要的 <-----这8位
exit(0)---->00000000 00000000 00000000 00000000 ----->  0000 00001------>256--->1 0000 0000   2------>512-->10 0000 00003------>768-->11 0000 0000         
=================================
格式:
pid_t waitpid(pid_t pid, int *wstatus, int options);
功能:接收子进程的退出状态值,回收子进程资源,可以设置非阻塞
参数:pid_t pid:< -1  例如-1234,先取绝对值 1234进程组id,获取当前进程组下的任意子进程-1    回收当前进程下的任意子进程0     回收当前进程组下的任意子进程> 0   例如1234,回收指定进程id为1234的进程int *wstatus:该指针中存储子进程的退出状态值写NULL,不接收子进程的退出状态值int options:0:表示阻塞WNOHANG:设置为非阻塞,如果没有子进程退出,则立刻返回
返回值:如果获取到子进程资源,则返回子进程的PID号如果第三个参数中指定WNOHANG,并且没有接收到子进程的资源,此时返回0失败返回-1,跟新errno
--------------------------------        
wait(&wstatus)等价于waitpid(-1, &wstatus, 0);wait函数默认阻塞函数,子进程不退出,则父进程永久阻塞,父进程不可以做自己的事
waitpid可以设置为非阻塞形式,子进程没有退出,直接向下继续运行,有课回收不到子进程
信号接收

5)vfork(创建子进程)

格式:#include <sys/types.h>#include <unistd.h>pid_t vfork(void);
功能:创建子进程的,子进程和父进程共用用户空间,先执行子进程后执行父进程返回值:
返回值:成功在父进程中返回子进程PID,子进程中返回0失败返回-1,跟新errno    

9、特殊进程

1)僵尸进程

1.僵尸进程指 子进程退出了,但是父进程没有回收子进程资源
2. 僵尸进程无法通过 kill 杀死,因为他已经是死掉的进程了
3. 僵尸进程是有害的,必须回收,因为僵尸进程会占用PCB和CPU资源
4. 回收僵尸进程

使用wait回收进程:由于wait是阻塞函数,会影响父进程

使用waitpid设置非阻塞模式:会导致可能接收不到资源

因此:

可以信号和 wait | waitpid 配合使用,防止僵尸进程的出现

或者杀死僵尸进程的父进程,进程1会收养孤儿进程,进而回收是孤儿进程的僵尸进程

2)孤儿进程

1. 孤儿进程:父进程结束,子进程没有结束,子进程默认会被1号进程收养

2. 孤儿进程是活的进程,是无害的,可以使用 kill 杀死

3.独立于终端,不可以使用 crlt c 结束进程,要使用 kill 杀死进程

4. 孤儿进程一般用于系统的后台进程

3)守护进程(幽灵进程)

1. 守护进程:例如操作系统的后台进程,随着操作系统的启动(结束)而启动(结束);

2. 运行在后台,不会因为终端(前端)的结束而结束

3. 不会在当前终端打印信息

4. 周期性的执行在死循环中

4)创建守护进程

作业:

1. 创建一个进程扇

2. 创建一个进程链

3.解析以下程序

打印顺序:
process_2
process_1
procsee

4. 实现文件的拷贝,父进程拷贝前一部分,子进程拷贝后一部分

http://www.lryc.cn/news/579214.html

相关文章:

  • Rust实现黑客帝国数字雨特效
  • CppCon 2018 学习:Feather: A Modern C++ Web Development Framework
  • FPGA的开发流程
  • 旋转不变子空间( ESPRIT) 算法
  • 基于SpringBoot的场地预定管理系统
  • 新版本没有docker-desktop-data分发 | docker desktop 镜像迁移
  • 当AR遇上深度学习:实时超声肾脏分割与测量技术全解析
  • FastAPI 安装使用教程
  • 人脸活体识别3:C/C++实现人脸眨眼 张嘴 点头 摇头识别(可实时检测)
  • 回顾JAVA中的锁机制
  • 重塑智能体决策路径:深入理解 ReAct 框架
  • WPF路由事件:冒泡、隧道与直接全解析
  • 嵌入式软件面经(四)Q:请说明在 ILP32、LP64 与 LLP64 三种数据模型下,常见基本类型及指针的 sizeof 值差异,并简要解释其原因
  • 软件开发早期阶段,使用存储过程的优势探讨:敏捷开发下的利器
  • 【C++】--入门
  • 欧拉角、四元数和旋转矩阵的变换关系以及无人机的坐标变换
  • 如何在Excel中每隔几行取一行
  • sqlmap学习笔记ing(3.[MoeCTF 2022]Sqlmap_boy,cookie的作用)
  • LeetCode Hot 100 滑动窗口 【Java和Golang解法】
  • 鸿蒙开发技巧---去除字符串两端的空格
  • AI大模型如何重塑软件开发流程?从自动化革命到人机共生范式
  • 怎样理解:source ~/.bash_profile
  • 深入Flink核心概念:解锁大数据流处理的奥秘
  • SAP WM LT10 TO创建增强
  • Android Auto即将带来变革
  • Agno(一)
  • 机器学习在智能制造业中的应用:质量检测与设备故障预测
  • Vue + RuoYi 前后端分离入门手册
  • Ubuntu云服务器上部署发布Vite项目
  • Redis基础(1):NoSQL认识