进程基本概念

时间:2021-03-12 14:53:15

基本概念

  • 课本概念:进程是执行程序的动态过程(程序是一组静态指令,程序是进程运行的静态文本)
  • 内核概念:进程是担当系统分配资源(如CPU时间、内存)的实体
  • PCB:进程信息被存放在一个叫做进程控制块的数据结构中,即PCB,可将其理解为进程属性的集合;在Linux下的PCB称为task_struct
  • task_struct是Linux的一种数据结构,它会被装载到Linux内存(RAM)中,用来存放进程信息
  • 进程具有的特点有:竞争性、独立性、并行、并发

task_struct内容分类

  • 标识符:描述本进程的唯一标识符,用来区别其他进程
  • 状态:任务状态,退出代码,退出信号等
  • 优先级:相对于其他进程的优先级
  • 程序计数器:程序中即将被执行的下一条指令的地址
  • 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  • 上下文数据:进程执行时处理器的寄存器中的数据
  • I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表
  • 记账信息:可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等

    Linux下查看进程信息的指令为:ls /proc/,如下图
    进程基本概念
    进程id:PID
    父进程id:PPID

进程调度算法

  • 先来先服务(FCFS):进程按照它们请求CPU的顺序使用CPU,哪一个进程先来则优先使用CPU,且在进程执行过程中不会被中断。
    优点:简单、易实现,只需一个队列
    缺点:有利于长进程,不利于短进程,有利于CPU繁忙的进程,不利于I/O繁忙的进程

  • 最短作业优先(SJF):对预执行时间短的进程优先分配处理机,且后面来的进程不会抢占处理机
    优点:改善平均周转时间和平均带权周转时间,缩短进程的等待时间,提高系统的吞吐量
    缺点:对长进程不利,可能会使其长时间不能执行,且不能根据进程的紧迫程度来划分执行的优先级,以及难以准确估计进程的执行时间,从而影响调度性能

  • 最高响应比优先(HRRN):同时考虑每个作业的等待时间长短和需要的执行时间长短,从中选出响应比最高的作业优先执行,是对FCFS和SJF的一种综合
    优点:因为长作业也有可能运行,所以在同一时间内处理的作业数要少于SJF法,HRRN的吞吐量小于SJF算法的吞吐量
    缺点:每次调度前都要计算响应比,增加了系统开销
  • 时间片轮转:周期性地进行进程周转

进程状态:

  • R运行状态(running):不意味着进程一定在运行中,它表明进程要么在运行中,要么在运行队列中
  • S睡眠状态(sleeping):意味着进程在等待事件完成,也叫可中断睡眠
  • D磁盘休眠状态(disk sleep):有时也叫不可中断睡眠状态,在这个状态的进程通常会等到IO的结束
  • T停止状态(stopped):可以通过SIGSTOP信号给进程来停止(T)进程,这个被暂停的进程可通过发送DIGCONT信号让进程继续运行
  • X死亡状态(dead):只是一个返回状态,在任务列表里看不到此状态

Z-僵尸进程

僵尸状态较为特殊,当进程退出但父进程没有读取到子进程退出的返回代码时,就会产生僵尸进程;僵尸进程会以终止状态保持在进程表中,并且会一直等待父进程读取退出状态代码,所以只要子进程退出,父进程还在运行,父进程没有读取子进程状态,子进程就会进入Z状态。

创建一个维持30s的僵尸进程代码如下:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3  int main(){
  4    pid_t id=fork();
  5    if (id<0)){
  6    perror("fork");
  7    return 1;
  8    }
  9  else if(id>0){  //parent
 10    printf("parent[%d] is sleeping...\n",getpid());
 11    sleep(30);
 12  }
 13  else{
 14    printf("child[%d] is begin Z...\n",getpid());
 15    sleep(5);
 16    exit(EXIT_SUCCESS);
 17  }
 18  return 0;
 19 }

僵尸进程会导致的问题有:
1)若父进程一直不读取子进程退出的返回代码,那么子进程就会一直处于Z状态;
2)因为进程没有退出,所以PCB会一直对其进行维护;
3)可能会造成内存泄漏;
4)浪费内存空间。

孤儿进程

若父进程先退出,子进程后退出进入Z状态后,子进程就被称为“孤儿进程”,且孤儿寄存被1号init进程领养。
创建孤儿进程代码如下:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 
  5 int main(){
  6    pid_t id=fork();
  7    if (id<0)){
  8    perror("fork");
  9    return 1;
 10    }
 11  else if(id==0){  //child
 12    printf("I am a child,pid: %d\n",getpid());
 13    sleep(10);
 14  }
 15  else{  //parent
 16    printf("I am your parent ,pid: %d\n",getpid());
 17    sleep(3);
 18    exit(0);
 19  }
 20  return 0;
 21 }

查看系统进程

使用ps -l 命令:
进程基本概念
其中几个重要信息是:
UID:代表执行者身份;
PID:代表这个进程的代号;
PPID:代表这个进程是由哪个进程发展衍生而来的,既是父进程代号;
PRI:代表这个进程的优先级,值越小越早被执行;
NI:代表此进程的nice值(nice值表示进程可被执行的优先级的修正数值,PRI值加入nice值后,PRI值会发生变化;nice值为负时,则值变小,也就是优先级变高)

环境变量

环境变量一般指在操作系统中用来指定操作系统运行环境的一些参数。
与环境变量相关的命令:

  • echo:显示某个环境变量的值;
  • export:设置一个新的环境变量;
  • env:显示所有环境变量;
  • unset:清除环境变量;
  • set:显示本地定义的shell变量和环境变量