二、多任务并发

单任务:程序运行起来,只能处理一件事情

多任务:程序运行起来,可以同时处理多件事情

1. 进程

1.什么是进程

进程:正在执行的程序,执行过程中需要消耗CPU和内存。

进程是操作系统资源分配的最小单位。

程序:

  1. 存放在硬盘的数据指令集合

  2. 静态的

  3. 程序运行起来时,可以创建出多个进程

进程:

  1. 进程是一个正在执行的程序,在内存中执行指令

  2. 进程是一个动态的过程,具备一定的生命周期

  3. 进程可以实现并发(多任务)

  4. 执行过程中需要消耗CPU和内存,多进程间存在资源竞争

2. 创建进程

进程在被创建的时候,操作系统需要为其分配0-4G的虚拟内存空间。

3. 进程的调度

宏观并行 从宏观角度,多个任务同时执行 微观串行 微观角度,多个任务按照一定顺序先后执行

CPU任务调度算法:

  1. 时间片轮询

  2. 先来先服务,后来后服务

  3. 优先级算法:高优先级先执行,低优先级后执行

  4. 短作业优先算法

4. 进程的状态

任何操作系统进程状态切换图:三态图

Linux操作系统进程状态切换:

 Linux进程状态:
    1.运行态(用户运行态、内核运行态)  R
        正在执行,且被CPU任务调度所执行的进程
        
    2.就绪态   R
        正在执行,没有CPU任务调度执行的进程(只缺少cpu)
        
    3.可唤醒等待态    S
        也称为睡眠态,阻塞等待资源的进程
        
    4.不可唤醒等待态 D
        不想被CPU任务调度所打断的进程任务可以设置为不可唤醒等待态
        
    5.暂停态   T
        被暂停执行的进程
        
    6.僵尸态    Z
        进程执行结束,空间没有被回收
        
    7.结束态    X
        进程执行结束,空间被回收
 ```

5. 进程的退出和消亡

进程执行结束,需要对进程对应的资源空间进行回收,否则,该进程进入僵尸态。

6. 进程相关的命令
  • ps -aux

    查看当前操作系统中的进程相关信息

    USER PID(进程ID号)

    ps -aux | grep a.out

    | 管道 :将前面的命令的输出作为后面命令的输入

    grep : 查找后面的字符串对应的信息

  • top

    动态查看进程的相关参数:侧重于CPU和内存占有率

  • ps -ef

    产看进程的父进程ID号

    父进程:产生子进程的进程叫父进程

    子进程:父进程产生的新进程称为该父进程的子进程

  • pstree

    查看进程的族谱关系

    pstree -sp PID

    查看指定进程的族谱关系

  • kill

    给进程发送一个信号

    kill -信号的ID/信号名称 PID

    kill -9 PID ---》结束PID对应的进程

    kill -19 PID ---》让进程进入到暂停态

    kill -18 PID ---》让进程继续运行

  • jobs

查看当前终端的后台进程及编号

  • fg 编号

将一个后台进程调到前台

7. 进程相关函数
  1. 创建进程fork

pid_t fork(void);
功能:创建新进程
返回值:
    成功:父进程中返回子进程的PID号
         子进程中返回0
    失败:-1

1.子进程在创建时,完全拷贝父进程0-3G的虚拟内存空间 ​ 文本区 ​ 数据区 ​ 堆区 ​ 栈区 ​ 2.拷贝内核空间中进程控制块(PCB)的部分内容 ​ PID号不拷贝

3. 父进程和子进程用户空间独立,数据不能共享,要想共享数据,需要使用进程间通信的方法

pid_t getpid(void);
功能:获取当前进程的PID号
pid_t getppid(void);
功能:获取当前进程的父进程的PID号(PPID)

练习:创建2个进程,分别打印自己的ID号和自己父进程的ID号,要求1s打印一

  1. 进程的消亡

    • 进程退出

      1. 在主函数中return;

      2. exit(),库函数,直接结束一个进程,结束前会刷新缓冲区

      3. _exit(), _Exit(),系统调用,直接结束一个进程,结束前不会刷新缓冲区

      4. 被动退出:异常退出、使用signal结束一个进程(kill)

    • 回收进程空间

      僵尸进程:子进程结束后,父进程没有回收子进程的资源空间,此时,该子进程成为僵尸进程。

      如何避免僵尸进程:

      1. 子进程结束,由其父进程回收资源空间

      2. 让子进程成为一个孤儿进程

      孤儿进程 :父进程先结束,其父进程创建的子进程成为孤儿进程,将会被系统进程收养,结束时由系统进程回收。

      比如:守护进程

    • 进程空间回收策略:

      1.对于一直处于运行状态,不会结束的进程不需要回收

      2.进程在执行有结束的情况时回收

    • 进程资源空间回收:

      wait

    pid_t wait(int *wstatus);
    功能:阻塞等待回收僵尸态进程
    参数:
        wstatus:保存回收的子进程的退出状态
    返回值:
        成功:返回回收到的子进程的ID
        失败:-1
    WIFEXITED(wstatus)  是不是正常结束   
    WEXITSTATUS(wstatus) 使用这个宏去拿exit结束状态
    WIFSIGNALED(wstatus) 是不是收到了信号而终止的            
    WTERMSIG(wstatus)如果是信号终止的,那么是几号信号。

    waitpid

    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 选项:
                0  表示回收过程会阻塞等待
                WNOHANG 表示非阻塞模式回收资源。
    返回值:
        成功 返回接收资源的子进程pid
        失败  -1
        设定为非阻塞且没有回收到子进程返回0 
    ​
    waitpid(0,&status,0)   //默认阻塞  ==wait(&status);
    waitpid(0,&status,WNOHANG); // 非阻塞方式
    ​
    注意:使用waitpid以非阻塞方式回收时,要搭配轮询方式实现。
8 .exec函数族
功能:在一个进程中执行另外一个文件
int execl(const char *path, const char *arg, ...
                       /* (char  *) NULL */);
 功能:可以执行任意可执行文件
 参数:     
    path:要执行的文件的路径和名称
    arg:执行该文件需要的参数
int execlp(const char *file, const char *arg, ...
                       /* (char  *) NULL */);
功能:执行环境变量保存的系统路径下的可执行文件
参数:
    file:需要执行的文件的名称
    arg:执行该文件需要的参数
int execle(const char *path, const char *arg, ...
                       /*, (char *) NULL, char * const envp[] */);
int execv(const char *path, char *const argv[]);
功能:可以执行任意可执行文件
 参数:     
    path:要执行的文件的路径和名称
    argv:执行该文件需要的参数存放的指针数组
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],
                       char *const envp[]);
​
    l : list-----》列表         "ls", "-l"
    v : vector---->容器(数组)  
    p :path  ----》路径 exec会自动从PATH环境变量所保存的路径下去寻找
    e :env   ----》环境变量

exec原理:当执行exec时,系统将要执行的文件和进程中文本区的指令数据进行替换。

env : 查看系统中的环境变量
whereis 二进制/库   查看二进制。库对应的位置
Logo

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

更多推荐