操作系统:进程的基本概念

  进程是运行程序的抽象,进程和程序分别描述了程序的静态形式和动态特征,进程是操作系统分配资源的基本单位

一、进程的创建
fork()
pid_t fork(void);
父进程通过fork函数创建新的运行的子进程。子进程的拥有父进程用户地址空间的一个副本,包含父进程的代码段数据段、堆、共享库和用户栈。同时还获得父进程的所有打开文件描述符的副本。
父进程和子进程最大的区别就是返回值pid不一样,再父进程中返回值为子进程的pid,在子进程中,返回值为0。
exec函数族
//exec函数族
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
进程还可以使用exec来把新的程序加载到自己内存中执行。新的程序会替换掉原来的代码段数据段、堆、共享库和用户栈。

二、进程描述符(进程控制块,PCB)
进程描述符(也叫进程控制块)是内核用于对进程的属性和行为进行记录的数据结构(Linux下为task_struct),包括优先级、状态、虚拟地址空间等等。
字段 说明
调度状态 进程的状态,如“就绪”,“挂起”等,以及其他调度信息,例如优先级值,自从进程获得CPU控制或自从获得控制以来经过的时间它被暂停了。同样,在流程暂停的情况下,必须为该流程正在等待的事件记录事件标识数据。
结构信息 进程的子进程ID,或以某种功能方式与当前进程相关的其他进程的ID,可以表示为队列,环或其他数据结构。
进程间通信信息 与独立进程之间的通信关联的标志,信号和消息
特权 允许/禁止访问系统资源
进程状态 新建,就绪,运行中,等待中,已死
进程号(PID) 每个进程的唯一标识号(也称为进程ID)
程序计数器(PC) 指向要为此过程执行的下一条指令的地址的指针
CPU寄存器 寄存器集,需要在其中存储过程以在运行状态下执行
CPU调度信息 CPU调度时间
内存管理信息 页表,内存限制,段表
统计信息 用于进程执行的CPU数量,时间限制,执行ID等
I / O状态信息 分配给进程的I / O设备列表。
 
进程描述符中的进程ID(pid)是操作系统中进程的唯一标识,常见的进程的pid如下:
pid 进程
0 上帝进程,idle
1 内核启动进程,init
2 内核调度进程,kthreadd
若想详细了解进程描述符,转至 https://www.cnblogs.com/linhaostudy/p/9568775.html
三、进程状态
进程每个时刻都处于某个状态,可能的状态有6个。
标号 状态名 状态标识 说明
1 可运行 TASK_RUNING 进程立刻或正在CPU上运行,运行的时机取决于调度器。
2 可中断的睡眠 TASK_INTERRUPTIBLE 进程等待某个事件(网络连接,信号量等)到来时进入此状态,并进入等待队列。当事件发生时,进程会被唤醒。
3 不可中断的睡眠 TASK_UNINTERRUPTIBLE 与可中断的睡眠区别就是不可被打断,不会相应任何信号。
4 暂停或跟踪
TASK_STOPPED
TASK_TRACED
暂停状态,向进程发送SIGSTOP信号,进程进入暂停状态(除了状态3)。向暂停状态的进程发送SIGCONT信号,进程转向可运行态。
跟踪状态,进程会暂停,并等待另一个跟踪进程对它执行的操作。例如GDB调试工具在程序中设置了一个断点,进程运行到断点处暂停比进入跟踪状态。
向跟踪状态的进程发送SIGCONT没有效果,只有当跟踪程序进行相应的系统调用或者退出后,进程才会恢复运行。
5 僵尸
TASK_DEAD
EXIT_ZOMBIE
进程即将结束,大部分资源被回收,只保留了一些信息。
6 退出
TASK_DEAD
EXIT_DEAD
进程结束,不保留任何信息直接退出。
父进程显示忽略SIGCHID信号。
子进程与父进程分离,运行的是全新的程序(exec)。
进程状态转换图
精简版进程状态转移图

四、进程空间
用户进程使用虚拟内存中的用户地址空间,每个进程的视角都是使用整个用户地址空间。
内核态和用户态
操作系统为了安全性和稳定性需要一种机制来限制进程可以执行的指令和访问的地址空间范围。
CPU通过设置控制寄存器的模式位来决定进程的运行模式。
  1. 当设置了模式位后,进程运行在内核态下,可以执行系统的任何指令,可以访问任何内存位置。
  2. 没有设置模式位,进程运行在用户态下,不能执行系统的特权指令,只能访问用户地址空间。
Linux中的/proc文件是用户进程可访问的内核数据信息,比如CPU类型。
系统调用
用户进程想要系统底层的功能需要通过系统调用的方式,系统调用指用户进程通过操作系统提供的接口来使用内核功能的行为。系统调用过程如图。

五、进程切换和调度
也叫上下文切换,任何一个时刻CPU上只有一个进程在运行。
上下文(context)是内核重新启动一个被抢占的进程所需要的状态。主要包含寄存器、程序计数器、用户栈、内核栈和各种内核数据结构,比如页表、进程表和已打开文件的文件表。
内核会为每个进程维护一个上下文,内核来负责进程的调度,采用抢占式的方法。
当内核选择一个新的进程运行时:
  1. 保存当前进的上下文。
  2. 恢复之前某个被抢占的进程的上下文。
  3. 将控制传递给这个新的进程。

 
六、进程间通信(IPC,Inter-Process Communication)
  1. 基于通信的IPC
    • 数据传送:管道、消息队列
    • 共享内存,最快的IPC
  2. 基于信号的IPC
    • 操作系统signal,异步IPC
  3. 基于同步的IPC
    • 信号量
 
posted @ 2020-05-20 16:51  skyliulu  阅读(162)  评论(0编辑  收藏  举报