多道程序设计技术是现代操作系统的基础。在进程并发执行时。各个协同进程运行次序的不同会导致不同的运行结果,从而出现运行错误。
数据不一致性
多道程序设计技术和多核处理器在观代操作系统中广泛应用,系统中的多个进程并发或并行执行已经成为常态。每个进程可在任何时候被中断,仅仅进程的部分代码片段可连续执行。
共享数据并发/并行访问:数据不一致性,又称不可再现性:同一进程在同一批数据上多次运行的结果不一样。
数据不一致性例子:有界缓冲
例子:n个缓冲区的有界缓冲问题
- 增加变量counter,初始化为0;
- 向缓冲区增加一项时,counter加1;
- 从缓冲区移去一项时,counter减1。
- 数据结构:
Shared data
#define BUFFER SIZE 10
typedef struct{
...
}item;
item buffer[BUFFER_SIZE];
int in=0;int out=0;
int counter=0;
生产者进程enter()
item nextProduced;
while(1){
while(counter==BUFFER_SIZE)
;/*do nothing*/
buffer[in]=nextProduced;
in=(in +1)%BUFFER_SIZE;
counter++;
}
消费者进程remove()
item nextConsumed;
while(1){
while(counter==0)
;/*do nothing*/
nextConsumed=buffer[out];
out=(out +1)%BUFFER_SIZE;
counter- -;
}
“counter++”的伪机器语言:
(SO)register1=counter
(S1)register1=register1+1
(S2)counter=register1
“counter–”的伪机器语言:
(S3)register2=counter
(S4)register2=register2-1
(S5)counter=register2
例题:
在有界缓冲问题中,生产者中的语句counter++和消费者中的语句counter—对应的伪机器指令如下:
“counter++”的伪机器语言:
(S0)register1 = counter
(S1)register1 = register1 + 1
(S2)counter = register1
“counter—”的伪机器语言:
(S3)register2 = counter
(S4)register2 = register2 – 1
(S5)counter = register2
假如当前counter=2,则可能存在()种不同的执行结果。
A. 1
B.2
C.3
D.以上都不对
C
运行错误例子:
初时counter=5:
S0:register1=counter {register1=5}
S1:register1=register1+1 {register1=6}
S3:register2=counter {register2=5}
S4:register2=register2-1 {register2=4}
S2:counter=register1 {counter=6}
S5:counter=register2 {counter=4}
解决方法:
规定这6个语句的运行次序,把counter++和counter–的语句分别作为一个整体来运行,也就是counter++或counter–的三个语句必须分别连续运行,不可中断。
例如:
原子操作:一个操作在整个执行期间不能被中断。
导致数据不一致性的原因:
竞争条件:多个进程并发访问同一共享数据,而共享数据的最终结果取决于最后操作的进程。
防止竞争条件方法:并发进程同步或互斥。
同步和互斥
同步:协调进程的执行次序,使并发进程间能有效地共享资源和相互合作,保证数据一致性。
协调执行次序。
互斥:进程排他性地运行某段代码,任何时候只有一个进程能够运行。
临界资源
-
临界资源是指一次只允许一个进程使用的资源,又称互斥资源、独占资源或共享变量。
-
共享资源:一次允许多个进程使用的资源。
-
临界资源例子:
许多物理设备都属于临界资源,如输入机、打印机、磁带机等,还有上例中的counter属于临界资源。
临界区
临界区是指涉及临界资源的代码段。
临界区是代码片段;
是进程内的代码;
每一个进程有一个或多个临界区;
临界区的设置方法由程序员确定。
若能保证诸进程互斥进入关联的临界区,可实现对临界资源的互斥访问。
临界区例子:
临界区使用准则
如何实现进程之间互斥使用临界区,从而保证数据的一致性呢?
- 互斥
假定进程Pi在某个临界区执行,其他进程将被排成在该临界区外;
有相同临界资源的临界区都需互斥;
无相同临界资源的临界区不需互斥。 - 有空让进
临界区内无进程执行,不能无限期地延长下一个要进临界区进程的等待时间。
意思就是每个离开临界区的进程应该开放临界区,让等待进入的进程可以进入。 - 有限等待
每个进程进入临界区前的等待时间必须有限,不能无限等待。
意思就是每个进程的临界区大小必须尽可能小,否则其他进程可能长时间等待。
访问临界区过程:
- 在