多任务(并发):让系统具备同时处理多个任务的能力
1. 多进程
2. 多线程
3. 进程间通信
一、进程的基本概念
1. 什么是进程?
正在运行的程序,其运行过程中需要消耗内存和CPU。
进程的特点:
动态性:进程是程序运行的一次执行过程,有创建、运行、结束等生命周期。
独立性:每一个进程拥有其独立的内存空间和系统资源,相互之间一般不直接干扰。
并发性:操作系统可以同时运行多个进程,通过CPU调度实现。
2.程序和进程有什么区别?
程序(Program)
定义:是一组静态的数据集合,存储在硬盘空间,是计算机执行特定任务的代码和数据的集合。
程序运行起来可以产生进程;
一个程序可以产生多个进程
特点:静态的:不运行时只是一堆代码和数据,不占用系统资源(除了磁盘空间)。
可复用的:同一个程序可以被多次执行(例如多次打开同一个软件)。
持久的:程序文件会长期保存在存储设备中,直到被主动删除。
进程(Process)
定义:进程是程序的一次动态执行过程,是操作系统进行资源分配和调度的基本单位。当程序被加载到内存中运行时,就成为了进程。
特点:动态性:进程是程序运行的一次执行过程,需要消耗内存和CPU,有创建、运行、结束等生命周期。
独立性:每一个进程拥有其独立的内存空间和系统资源,相互之间一般不直接干扰。
并发性:操作系统可以同时运行多个进程,通过CPU调度实现。
一个进程中也可执行多个程序
二、进程的产生
进程产生时,操作系统都会为其分配0-4G的虚拟内存空间。
三、进程的调度
CPU:数据处理速度快
宏观并行,微观串行
cpu调度算法
1、时间片轮询算法
2、先来先服务,后来后服务(任务队列)
3、短作业优先调度
4、高优先级先执行,低优先级后执行
四、进程的状态
操作系统进程进程三态图:
Linux操作系统的进程状态:
1.运行态(用户运行态、内核运行态) R
正在执行,且被CPU任务调度所执行的进程
2.就绪态 R
正在执行,没有CPU任务调度执行的进程(只缺少cpu)
3.可唤醒等待态 S
也称为睡眠态,阻塞等待资源的进程
4.不可唤醒等待态 D
不想被CPU任务调度所打断的进程任务可以设置为不可唤醒等待态
5.暂停态 T
被暂停执行的进程
6.僵尸态 Z
进程执行结束,空间没有被回收
7.结束态 X
进程执行结束,空间被回收
五、进程的消亡
1. 进程执行结束(进程退出)
2. 回收进程资源空间
六、进程相关命令
PID:进程的ID号
PPID :父进程ID号
父进程:产生子进程的进程称为父进程
子进程:父进程产生出来的新进程即为该父进程的子进程
1. ps -aux
查看进程相关参数:PID、状态、CPU占有率、内存占有率
ps -aux | grep ./a.out
| : 管道 :前面命令的输出作为后面命令的输入
grep : 字符串查找:在输入中查找和后面字符串相关的数据
2. top
动态查看进程的相关参数:CPU占有率、内存占有率
3. ps -ef
查看该进程的ID和父进程ID
4. pstree
查看进程的产生关系
pstree -p
查看进程的产生关系(有PID号)
pstree -sp 进程PID号
查看某个指定的进程的产生关系
5. kill -信号的编号/信号的名称 PID
向进程发送信号,让进程的状态发生变化
kill -l
查看系统支持的信号
结束一个进程:
kill -9 PID
kill -SIGKILL PID
killall -9 进程名称
+前台进程
后台进程
jobs
查看当前终端的后台进程
fg 后台进程编号
让后台进程切换成前台进程
七、进程相关编程
1.fork函数
需要的头文件:#include <sys/types.h> #include <unistd.h>
函数原型:pid_t fork(void);
功能:复制当前进程(父进程),生成一个新进程(子进程)。
复制特性:
子进程完全拷贝父进程0-3G的虚拟内存空间,但两者拥有独立的地址空间,后续修改互不影响
子进程拷贝父进程PCB(进程控制块)块中的部分内容:PID不拷贝
返回值:
关键特点:调用一次,返回两次:
父进程中,fork()返回子进程的进程ID(PID,非负整数)
子进程中,fork()返回0。
若创建失败,父进程会返回-1。
执行顺序:父进程和子进程的执行顺序由操作系统调度器决定,不确定谁先运行。
getpid(); 获取当前进程自己的PID号
getppid():获取当前进程父进程的PID号
注意:
1. 子进程完完整整拷贝父进程0-3G虚拟内存空间。
2. 父子进程栈区、数据区、文本区、堆区完全独立,数据不共享
3. 要想共享数据,需要使用进程间通信方式实现
练习:
1. 使用fork函数创建新进程,父进程打印自己的PID和自己子进程的pid,子进程中打印自己的PID和父进程的PID
#include<stdio.h>int main()
{pid_t pid = fork;if(pid > 0){printf("自己的PID:%d 自己子进程的PID",getpid(),pid);}else if(pid == 0){printf("自己的PID:%d 自己父进程的PID",getpid(),getppid());}else if{perror(fork error);}return 0;
}
2.进程调度:操作系统完成
1.进程退出:return、exit()相关函数
1)main中return
2) exit ()、_exit() :结束一个进程
exit (0) : 正常退出
exit (非0) :由于进程产生了某种问题,需要主动退出进程
2.回收资源空间:wait()、waitpid()
僵尸进程:父进程未回收已终止子进程的资源, 退出后,但其资源空间未被父进程回收
如何避免僵尸进程产生:
1. 子进程退出后,父进程及时为其回收资源空间
2. 让该进程成为一个孤儿进程,结束时被操作系统中的系统进程回收
孤儿进程:父进程先消亡,其对应的子进程成为一个孤儿进程,会被系统进程所收养
(守护类的进程)