Linux中的进程

进程相关概念

一、程序和进程

什么是程序?

程序是完成特定任务的一系列指令集合

什么是进程?

  • 从用户的角度来看进程是程序的一次执行过程
  • 从操作系统的核心来看,进程是操作系统分配的内存、CPU时间片等资源的基本单位
  • 进程是资源分配的最小单位
  • 每一个进程都有自己独立的地址空间与执行状态

像UNIX这样的多任务操作系统能够让许多程序同时运行,每一个运行着的程序就构成了一个进程

进程和程序是有本质区别的:

  • 程序是静态的,它是一些保存在磁盘上的指令的有序集合,没有任何执行的概念;
  • 而进程是一个动态的概念,它是程序执行的过程,包括了动态创建、调度和消亡的整个过程;
  • 进程是程序执行和资源管理的最小单位

二、并行和并发

并行性包含同时性和并发性,前者是指两个或多个事件在同一时刻发生,后者是指两个或多个事件在同一时间段内发生。

上面表示的是并发,只有一台咖啡机,相当于只有一个CPU,大家每人接一口,而不是接一杯。使得在某一个时间段内都能喝到咖啡;下面表示的是并行,有两台咖啡机,同一时间点可以有两个人同时接到咖啡,相当于多CPU工作。

三、pcb(处于进程地址空间的内核区)

进程控制块(Processing Control Block),是操作系统核心中一种数据结构,主要表示进程状态。其作用是使一个在多道程序环境下不能独立运行的程序(含数据),成为一个能独立运行的基本单位或与其它进程并发执行的进程。或者说,OS是根据PCB来对并发执行的进程进行控制和管理的。 PCB通常是系统内存占用区中的一个连续存区,它存放着操作系统用于描述进程情况及控制进程运行所需的全部信息,它使一个在多道程序环境下不能独立运行的程序成为一个能独立运行的基本单位或一个能与其他进程并发执行的进程。

一些常见的记载信息

(1) 标识号。每个进程都有一个进程标识号(PID)和一个父进程标识号(PPID),其中PID唯一标识一个进程。另外,一个进程还有自己的用户标识号(UID)和组标识号(GID),系统通过这两个标识号判断进程对文件或设备的访问权。
(2) 状态信息。一个 Linux 进程可有如下几种状态:运行、等待、停止和僵死。
(3) 调度信息。调度器根据这些信息判定系统中哪个进程最迫切需要运行。
(4) 有关进程间通讯的信息。系统利用这一信息实现进程间的通讯。
(5) 进程与其他进程之间的关系信息:在 Linux 系统中,除根进程之外,任何一个进程都具有父进程也可能有兄弟进程或子进程。所以每个进程的PCB中包含了进程的父进程指针、和该进程具有相同父进程的兄弟进程指针以及进程的子进程指针。另外,Linux 还利用一个双向链表记录系统中所有的进程,这个双向链表的根就是 init 进程。利用这个链表中的信息,内核可以很容易地找到某个进程。
(6) 时间和定时器信息。系统在这些字段中保存进程的建立时间,以及在其生命周期中所花费的 CPU 时间。Linux 也支持和进程相关的定时器,应用程序可通过系统调用建立定时器,当定时器到期,操作系统会向该进程发送sigalrm信号。
(7)文件系统信息。这类字段记录进程所打开的文件描述符信息。另外,还包含指向虚拟文件系统(Virtual File Systems,VFS)两个索引节点的指针,这两个索引节点分别是进程的主目录以及进程的当前目录。索引节点中有一个引用计数器,当有新的进程指向某个索引节点时,该索引节点的引用计数器会增加。未被引用的索引节点的引用计数为 0,因此,当包含在某个目录中的文件正在运行时,就无法删除这一目录,因为这一目录的引用计数大于0。
(8)虚拟内存与物理内存相关信息:每个进程均有自己的内存空间,为了让linux内核随时了解和控制进程的内存空间,PCB中必须保存进程内存空间的相关信息。

(9)和进程相关的上下文信息。进程上下文是用来保存进程相关的系统状态的字段。当调度程序将某个进程从运行状态切换到暂停状态时,会在上下文中保存当前的进程运行环境,包括 CPU 所有寄存器的值、进程的状态以及堆栈信息;当调度程序再次选择该进程运行时,则会从进程上下文信息中恢复进程的运行环境。

pcb的组织方式

1.线性方式,即将系统中所有的PCB组织在一张线性表中。

2.链接方式,即把具有相同状态进程的PCB分别通过PCB中的链接字链接成一个队列。

3.索引方式,建立几张索引表

四、进程的5种状态

创建状态:进程在创建时需要申请一个空白PCB,向其中填写控制和管理进程的信息,完成资源分配。如果创建工作无法完成, 比如资源无法满足,就无法被调度运行,把此时进程所处状态称为创建状态
就绪状态:进程已经准备好,已分配到所需资源,只要分配到CPU就能够立即运行
执行状态:进程处于就绪状态被调度后,进程进入执行状态
阻塞状态:正在执行的进程由于某些事件(I/O请求,申请缓存区失败)而暂时无法运行,进程受到阻塞。在满足请求时进入就   绪状态等待系统调用

终止状态:进程结束,或出现错误,或被系统终止,进入终止状态。无法再执行

引起进程阻塞和唤醒的事件

1.向系统申请资源时失败。如一个进程(A)申请打印机但是此时打印机被其他进程(B)正在使用,此时A进程则处于阻塞状态。

2.等待某种操作:进程A启动了某I/O设备,如果只有完成了指定的I/o任务后进程A才能执行,则进程A启动了I/O设备后会自动进入阻塞。

3.新数据尚未到达:对于相互合作的进程,如果一个进程需要先获得另一个进程的数据后才能对该数据进行处理,只要数据尚未到达其便会进入阻塞状态。

4.等待新任务的到达:每当这种进程完成自己的任务便把自己阻塞起来,等待新任务到达,才将其唤醒。

进程阻塞的过程:

正在执行的进程,如果遇到上面阻塞的事件后,进程便调用阻塞原语block将自己阻塞,(阻塞是进程自身的一种主动行为)并将正在运行的进程立即停止运行,并把PCB中进程状态信息改为阻塞,并将PCB插入阻塞队列,如果系统设置了不同阻塞原因的队列,则应将其插入到对应原因引起的阻塞队列中。

进程唤醒的过程:

当被阻塞进程所期待的事件发生时则有关的进程会调用唤醒原语(wakeup),将等待的进程唤醒,首先把阻塞的进程从阻塞队列中移出,将其PCB中的现行状态由阻塞改为就绪,然后将其PCB插入就绪队列中

应当指出,block原语和wakeup原语是一对作用刚好相反的原语。在使用它们时,必须成对使用。否则,阻塞进程将会因不能被唤醒而永久地处于阻塞状态,再无机会继续运行。

五、进程终止的八种方式

5种正常终止方式

(1)从main返回,也就是调用return 

(2)调用exit

(3)调用_exit或Exit;

(4)最后一个线程从其启动例程返回

(5)从最后一个线程调用pthread_exit

exit与_exit的区别:

从图中可以看出,_exit 函数的作用是:直接使进程停止运行,清除其使用的内存空间,并清除其在内核的各种数据结构;exit 函数则在这些基础上做了一些小动作,在执行退出之前还加了若干道工序。exit() 函数与 _exit() 函数的最大区别在于exit()函数在调用exit  系统调用前要检查文件的打开情况,把文件缓冲区中的内容写回文件。也就是图中的“清理I/O缓冲”。

示例:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值