计算机进程的控制通常由原语完成。所谓原语,一般是指由若干条指令组成的程序段,用来实现某个特定功能,在执行过程中不可被中断。在
操作系统中,某些被进程调用的操作,如队列操作、对信号量的操作、检查启动外设操作等,一旦开始执行,就不能被中断,否则就会出现操作错误,造成系统混乱。所以,这些操作都要用原语来实现 原语是操作系统核心(不是由进程,而是由一组程序模块组成)的一个组成部分,并且常驻内存,通常在管态下执行。原语一旦开始执行,就要连续执行完,不允许中断。
介绍
原语是在操作系统中调用核心层子程序的指令。与一般广义指令的区别在于它是不可中断的,而且总是作为一个基本单位出现。它与一般过程的区别在于:它们是“
原子操作(primitive or atomic action)”。所谓原子操作,是指一个操作中的所有动作要么全做,要么全不做。换言之,它是一个不可分割的基本单位,因此,在执行过程中不允许被中断。原子操作在管态下执行,常驻内存。原语的作用是为了实现进程的通信和控制,系统对进程的控制如不使用原语,就会造成其状态的不确定性,从而达不到
进程控制的目的。
分类
计算机网络中也有“原语”一词,它与操作系统的“原语”概念不同。服务原语是指协议中的下层协议通过接口为上层协议提供某种服务而发送的原语操作。
原语分为四类:请求(Req)型原语,用于高层向低层请求某种业务;证实(Cfm)型原语,用于提供业务的层证实某个动作已经完成;指示(Ind)型原语,用于提供业务的层向高层报告一个与特定业务相关的动作;响应(Res)型原语,用于应答,表示来自高层的指示原语已收到。
组成及功能
原语通常由若干条指令组成,用来实现某个特定的操作。通过一段不可分割的或不可中断的程序实现其功能。原语是操作系统的核心,它不是由进程而是由一组
程序模块所组成,是操作系统的一个组成部分,它必须在
管态(一种机器状态,管态下执行的程序可以执行特权和非特权两类指令,通常把它定义为操作系统的状态)下执行,并且
常驻内存,而个别系统有一部分不在管态下运行。原语和广义指令都可以被进程所调用,两者的差别在于原语有不可中断性,它是通过在执行过程中关闭中断实现的,且一般由系统进程调用。许多广义指令的功能都可用
目态(一种机器状态,通常把它作为
用户程序执行时的状态)下运行的系统进程完成,而不一定要在
管态下完成,例如文件的建立、打开、关闭、删除等广义指令,都是借助中断进入管态程序,然后转交给相应的进程,最终由进程实现其功能。引进原语的主要目的是为了实现进程的通信和控制。
异步原语
异步原语也叫做异步通信原语,是指与阻塞的通信原语相对应的是另一种称为非阻塞的通信原语。如果一个send原语是非阻塞的,它在消息实际发送之前,就立即把控制返回给调用者。也就是说,发送进程在发送消息时并不进入阻塞状态,它不等消息发送完就继续执行其后继语句。异步原语(又称非阻塞原语)的优点是明显的。发送进程可在消息实际发送过程中进行连续的工作,而不是让CPU空转(假定此时没有其它进程可以运行)。这就是说,采用非阻塞的通信原语可以大大提高系统的效率和处理机的利用率。然而,由非阻塞原语所带来的效率上的好处却被一个严重的缺点抵消了。这个缺点就是缓冲区中能使用一次,因为发送者在发送完消息之前,进程不能继续使用原来的缓冲区。倘若在消息传送期间修改缓冲区会带来可怕的后果,至于何时才能允许使用这个缓冲区,却无法得知。
进程控制块的原语
进程控制的主要任务,是对系统中所有进程从创建到消亡的全过程实行有效的管理和控制。这意味着它不仅对进程状态变化加以管理和控制,而且具有创建新进程和撤销已完成任务的进程的能力。
为了对进程进行控制,在操作系统中必须设置一个机构,它具有创建进程、撤销进程及其他管理功能。这是操作系统中最常用、最核心的内容,常称为内核。内核是计算机硬件的第一层扩充软件,是操作系统的管理和控制中心,其功能往往是通过执行各种原语操作来实现的。为了保证操作的正确性,原语在执行期间不可分割。原语一旦开始执行,直到完毕之前,是不允许中断的。在操作系统中,用于进程控制的原语主要有创建原语、撤销原语、阻塞原语、唤醒原语。
创建原语
在实际系统中创建一个进程有两种方法:一是由操作系统建立,O号进程就是由操作系统建立的;二是由其他进程创建一个新的进程。基本操作都是一样的。创建进程原语总是先为新建进程申请一空白PCB,并为之分配唯一的数字标识符,使之获得PCB的内部名称,若该进程所对应的程序不在内存中,则应将它从外存储器调入内存,并将该进程有关信息填入PCB中,然后置该进程为就绪状态,并将它排入就绪队列和进程家族队列中。
撤销原语
撤销进程的实质是撤销进程存在标志——
进程控制块PCB。一旦PCB被撤销,进程就消亡了。撤销原语的操作过程大致如下:以调用者提供的标识符Ⅱ为索引,从该进程所在的队列,将它从该队列中消去,并撤销属于该进程的一切“子孙进程”,若有父进程则从父进程PCB中删除指向该进程的指针,并释放撤销进程所占用的全部资源,或将其归还给父进程,或归还给系统。若被撤销的进程处于执行状态,应立即中断该进程的执行,并设置调度标识为真,以指示该进程被撤销后系统应重新调度。
阻塞原语
阻塞原语的大致工作过程如下:开始时,进程正处于执行状态,因此首先应中断CPU执行,并保存该进程的CPU现场,然后把阻塞状态赋予该进程,并将它插入具有相同实体的阻塞队列中。
唤醒原语
一进程因为等待事件的发生而处于阻塞状态,当等待的事件完成后,进程又具有了继续执行的条件,这时就要把该进程从阻塞状态转变为就绪状态,这个工作由唤醒原语来完成。唤醒原语执行的操作有:先把被唤醒进程从阻塞队列中移出,设置该进程当前状态为就绪状态,然后再将该进程插入到就绪队列中。
PV原语
PV原语通过操作信号量来处理进程间的同步与互斥的问题。其核心就是一段不可分割不可中断的程序。 信号量的概念1965年由著名的荷兰计算机科学家Dijkstra提出,其基本思路是用一种新的变量类型(semaphore)来记录当前可用资源的数量。semaphore有两种实现方式:
1) semaphore的取值必须大于或等于0。0表示当前已没有空闲资源,而正数表示当前空闲资源的数量;
2) semaphore的取值可正可负,负数的绝对值表示正在等待进入临界区的进程个数。
信号量是由操作系统来维护的,用户进程只能通过初始化和两个标准原语(P、V原语)来访问。初始化可指定一个非负整数,即空闲资源总数。
P原语
P是荷兰语Passeren(通过)的首字母。为阻塞原语,负责把当前进程由运行状态转换为阻塞状态,直到另外一个进程唤醒它。操作为:申请一个空闲资源(把信号量减1),若成功,则退出;若失败,则该进程被阻塞;
V原语
V是荷兰语Verhogen(增加)的首字母。为唤醒原语,负责把一个被阻塞的进程唤醒,它有一个参数表,存放着等待被唤醒的进程信息。操作为:释放一个被占用的资源(把信号量加1),如果发现有被阻塞的进程,则选择一个唤醒之。
P原语操作的动作是:
(1)sem减1;
(2)若sem减1后仍大于或等于零,则P原语返回,该进程继续执行;
(3)若sem减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度。
V原语操作的动作是:
(1)sem加1;
(2)若相加结果大于零,则V原语停止执行,该进程返回调用处,继续执行;
(3)若相加结果小于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度。
PV操作对于每一个进程来说,都只能进行一次,而且必须成对使用。在PV原语执行期间不允许有中断的发生。
具体PV原语对信号量的操作可以分为三种情况:
1) 把信号量视为一个加锁标志位,实现对一个共享变量的互斥访问。
实现过程:
P(mutex); // mutex的初始值为1 访问该共享数据; V(mutex); 非临界区;
2) 把信号量视为是某种类型的共享资源的剩余个数,实现对一类共享资源的访问。
实现过程:
P(resource); // resource的初始值为该资源的个数N 使用该资源; V(resource);非临界区;
3) 把信号量作为进程间的同步工具
实现过程:
临界区C1;P(S);V(S);临界区C2;