嵌入式学习(day27)多任务进程
多任务(并发)
- 定义:让系统具备同时处理多个任务的能力。
- 实现方式:1. 多进程 2. 多线程 3. 进程间通信
概念
1、 进程定义:正在运行的程序,其运行过程中需要消耗内存和 CPU。
程序与进程的区别:
- 程序:静态的数据集合,存储在硬盘空间。(程序运行起来可产生进程,一个程序可产生多个进程)
- 进程:程序动态执行的过程,需要消耗内存和 CPU。进程具备动态生命周期,从产生调度再到消亡、一个进程中也可执行多个程序。
2、进程的产生
进程产生时,操作系统都会为其分配0-4G的虚拟内存
(1)内核:1. 文件管理 2. 进程管理 3. 内存管理
(2)栈区:1. 保存局部变量 2. 函数的形参和返回值 3. 保存函数的调用关系(保护现场和恢复现场)
(3)堆区:1. 由开发人员手动分配 2. 使用完要手动释放
(4)data段:1. 已初始化的全局变量 2. 已初始化的静态变量
(5)bss段:1、 未初始化的全局变量 2、未初始化的静态变量(static)(程序启动时自动初始化为0)
(6)字符串常量区:保存字符串常量。
(7)文本区:存放指令代码 存放常量:‘A’ 10 0xAA
3、进程的调度
CPU数据处理速度快:宏观并行,微观串行。
CPU调度算法:
1. 时间片轮询算法
2. 先来先服务,后来后服务(任务队列)
3. 短作业优先调度
4. 高优先级先执行,低优先级后执行
4、进程的状态
操作系统操作三态图
5、进程的消亡
(1)进程执行结束(进程退出)
(2)回收进程资源空间
6、进程相关命令
PID:进程的 ID 号。
PPID:父进程的 ID 号。
父进程:产生子进程的进程称为父进程。
子进程:父进程产生出来的新进程即为该父进程的子进程。
(1). ps -aux
- 功能:查看进程的相关参数,包括 PID、状态、CPU 占有率、内存占有率。
ps -aux | grep ./a.out
- 功能:通过管道(`|`)将 `ps -aux` 的输出作为输入,使用 `grep` 查找与 `./a.out` 相关的进程信息。
管道 (`|`):
- 功能:前面命令的输出作为后面命令的输入。
grep
- 功能:在输入中查找与指定字符串相关的内容。
(2)、`top`
- 功能:动态查看进程的相关参数,包括 CPU 占有率和内存占有率。
(3)、 `ps -ef`
- 功能:查看该进程的 ID 和父进程 ID。
(4)、 `pstree`
- 命令及其功能:
- `pstree`:查看进程的产生关系。
- `pstree -p`:查看进程的产生关系(显示 PID 号)。
- `pstree -sp PID`:查看某个指定进程的产生关系。
(5)、`kill`
功能:
- `kill -信号的编号/信号的名称 PID`:向进程发送信号,让进程的状态发生变化。
- `kill -l`:查看系统支持的信号。
- 结束进程的方式:
- `kill -9 PID`:强制结束进程。
- `kill -SIGKILL PID`:强制结束进程。
- `killall -9 进程名称`:强制结束指定名称的所有进程。
7、进程相关编程
(1). 进程创建
- 函数:`fork()`
- 相关函数:
- `getpid()`:获取当前进程自己的 PID 号。
- `getppid()`:获取当前进程父进程的 PID 号。
(2)进程调度:由操作系统完成。
(3). 进程消亡
- 进程退出:使用 `return` 或 `exit()` 相关函数。
- 回收资源空间:使用 `wait()` 或 `waitpid()`。
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
fork()
:通过拷贝父进程产生一个新的子进程。- 子进程完全拷贝父进程的虚拟内存空间(0-3G)。
- 子进程拷贝父进程的 PCB(进程控制块)中的部分内容,但 PID 不被拷贝。
注意:
1. 子进程与父进程的内存空间关系:
子进程完整拷贝父进程的虚拟内存空间(0-3G)。
2. 父子进程的数据独立性:
父子进程的栈区、数据区、文本区、堆区完全独立,数据不共享。
3. 数据共享的方式:
如果需要共享数据,必须使用进程间通信方式实现。
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>int main(int argc,const char *argv[])
{//*p = 100;pid_t pid = fork();int *p = malloc(sizeof(int));if(pid < 0){perror("fork error");}else if(pid > 0){while(1){*p = 100;printf("I am father : pid = %d,spid = %d,*p = %d\n",getpid(),pid,*p);sleep(1);}}else{while(1){*p = 1000;printf("I am son :pid = %d ppid = %d,*p=%d\n",getpid(),getppid(),*p);sleep(1);}}return 0;
}
1. 进程退出
相关函数:
- `return`:在 `main` 函数中使用 `return`。
- `exit()` 和 `_exit()`:用于结束一个进程。
- `exit(0)`:正常退出。
- `exit(非0)`:由于进程产生了某种问题,需要主动退出进程。
2. 回收资源空间
- 使用的函数:
- `wait()`
- `waitpid()`
3. 僵尸进程
定义:进程退出后,但其资源空间未被父进程回收。
避免僵尸进程产生的方法:
1. 子进程退出后,父进程及时为其回收资源空间。
2. 让该进程成为一个孤儿进程,结束时被操作系统中的系统进程回收。
4. 孤儿进程
定义:父进程先消亡,其对应的子进程成为一个孤儿进程,会被系统进程所收养(守护类的进程)。