一 . 多任务

多任务:让程序具备同时处理多个任务的能力(并发)

如何实现多任务:多进程、多线程

1.进程

进程:正在执行的程序,需要消耗内存和CPU。
在这里插入图片描述

进程和程序的区别:

  1. 程序是一组数据指令集合,存储在硬盘空间,是静态的;
  2. 进程存储在内存空间,执行过程需要CPU参与(内存+CPU);
  3. 进程具备动态的生命周期,从启动到消亡。
  4. 程序运行起来产生一个进程;也可产生多个进程;
  5. 在一个进程中也可以执行多个程序。

2.进程的创建

./a.out ----->启动进程
进程在被创建的时候,操作系统会为该进程分配0-4G的虚拟内存空间。
进程是操作系统资源分配的最小单位。
在这里插入图片描述

3.进程的调度

CPU调度进程:
宏观并行,微观串行(并发)
并行:多个任务同时执行

CPU调度算法:

  1. 时间片轮询算法
  2. 先来先服务,后来后服务算法
  3. 高优先级优先执行算法
  4. 短作业优先算法

4.进程的状态

操作系统进程状态三态图:
在这里插入图片描述

Linux操作系统进程状态:
在这里插入图片描述
1.运行态(用户运行态、内核运行态) R
正在执行,且被CPU任务调度所执行的进程

2.就绪态 R
正在执行,没有CPU任务调度执行的进程(只缺少cpu)

3.可唤醒等待态 S
也称为睡眠态,阻塞等待资源的进程

4.不可唤醒等待态 D
不想被CPU任务调度所打断的进程任务可以设置为不可唤醒等待态

5.暂停态 T
被暂停执行的进程

6.僵尸态 Z
进程执行结束,空间没有被回收

7.结束态 X
进程执行结束,空间被回收

5. 进程的消亡

1. 进程退出

  1. 进程执行结束退出
  2. 主函数中遇到return退出
  3. exit(),exit() ,Exit()结束进程
  4. 通过信号结束一个进程(kill -9 进程ID)
    void exit(int status);
    功能:退出一个进程
    参数
    status:进程结束时的状态
    0:正常退出
    !0:因为其他原因退出

void _exit(int status);
void _Exit(int status);

2. 进程回收

6. 进程相关命令

1. ps -aux
查看操作系统所有进程的相关参数:PID(进程ID号)、创建者、状态、CPU占有率、内存占有率
ps -aux | grep a.out
| 管道:将前面的输出作为后面的输入
grep :字符串查找

2. ps -ef
查看操作系统所有进程的相关参数:PID、PPID
父进程:创建新进程的进程是该新进程的父进程
子进程:创建出来的新进程是子进程
PID : Process ID 进程ID号
PPID:父进程ID号

3. top
动态查看进程状态及CPU占有率、内存占有率

4. pstree
查看进程间的创建关系(族谱图)
pstree -sp 进程ID
查看指定ID的进程的创建关系

5. kill
kill -信号名称/信号ID PID
给PID对应的进程发送一个信号
kill -l 查看系统定义出来的信号
kill -9 PID :结束一个进程
S+ : 处于可中断睡眠状态的前台进程
S: 处于可中断睡眠状态的后台进程
T: 处于暂停态的后台进程

6. fg 后台进程编号
将后台进程调到前台
jobs :查看当前后台进程编号

7.进程相关的函数

fork()

子进程:操作系统通过完整拷贝父进程0-3G的用户空间数据到子进程。
内核空间拷贝部分内容:
PCB块
PID不拷贝
PPID不拷贝

程序执行的位置
文件管理

注意:

  1. 进程共用3G-4G这1G的内核空间;
  2. 但各自进程0-3G用户空间互相独立,不能互相通信。
  3. 进程间不能直接通信,要通信需要借助内核空间(IPC机制)
    在这里插入图片描述

pid_t fork(void);
功能:创建新的进程,新进程叫子进程,原来的进程叫父进程
参数:
返回值:
成功:父进程中返回子进程的PID号
子进程中返回 0
失败:-1,没有新进程被创建
getpid():获取当前进程自己的PID号
getppid():获取当前进程的父进程的PID号

僵尸进程和孤儿进程:

僵尸进程:进程已退出,但其资源空间没有被其父进程回收。

孤儿进程:父进程先结束,其父进程创建的子进程成为孤儿进程,将会被系统进程所收养,结束后,由系统进程回收。
比如:守护进程

如何避免僵尸进程产生:

  1. 由其父进程对僵尸态进程进行回收:wait()、waitpid()
  2. 让进程称为孤儿进程,结束后,由操作系统回收。

wait()

waitpid()

#include <sys/types.h>
#include <sys/wait.h>

exit

*pid_t wait(int wstatus);
功能:阻塞回收僵尸态的进程资源空间和状态,
参数
wstatus :用来存储进程退出时的状态参数
返回值
成功:回收到的子进程ID号
失败:-1
wait(NULL);

*pid_t waitpid(pid_t pid, int status, int options);
功能:回收指定进程的资源
和wait功能相似,比wait更灵活
参数
pid:
<-1 回收指定进程组内的任意子进程 (-100.等待GID=100的进程组中的任意子进程)
-1 回收任意子进程,组内外
0 回收和当前调用waitpid一个组的所有子进程,组内

0 回收指定ID的子进程
status 子进程退出时候的状态,
如果不关注退出状态用NULL;
options 选项

  1. 线程
    0 表示回收过程会阻塞等待
    WNOHANG 表示非阻塞模式回收资源。
    返回值: 成功 返回接收资源的子进程pid
    失败 -1
    设定为非阻塞且没有回收到子进程返回0
    waitpid如果以阻塞方式回收和wait使用方式一样
    如果父进程有任务需要执行,则可以选择waitpid非阻塞方式回收,此时搭配轮询方式实现。

8.exec函数簇

作用:在一个进程中,执行外部的一个可执行程序。
本质:exec将要执行的外部程序替换到了进程的文本区

int execl(const char *path, const char arg, …
/
(char *) NULL */);

参数
path :可执行行程序所在路径
“/bin/ls”
arg : 执行可执行程序时,传递的参数。
NULL :参数的结束标志
返回值
失败:-1
int execlp(const char *file, const char arg, …
/
(char *) NULL */);

功能:执行PATH环境变量保存的路径中的可执行程序
参数
file :可执行文件的名称
arg : 执行可执行程序时,传递的参数。
NULL :参数的结束标志

int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);

参数
path :可执行行程序所在路径
file :可执行文件的名称
argv :存放执行可执行程序时传递参数的指针数组
int execle(const char *path, const char arg, …
/
, (char *) NULL, char * const envp[ ] */);
int execvpe(const char *file, char *const argv[ ],
char *const envp[]);

l : list–》列表
p : PATH :环境变量 :保存了系统中已有的可执行程序的存放路径
v : vector :容器

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐