Chapter 6: Process Synchronization
问题的提出:彼此合作的进程之间可以用共享逻辑地址空间的方式来实现,共享逻辑地址空间,也就是共享代码区和数据区,会导致数据不一致,所以介绍一些避免数据不一致的机制。
6.1Background
Concurrent access to shared data may result in data inconsistency
Maintaining data consistency requires mechanisms to ensure the orderly execution of cooperating processes
Suppose that we wanted to provide a solution to the consumer-producer problem that fills all the buffers. We can do so by having an integer count that keeps track of the number of full buffers. Initially, count is set to 0. It is incremented by the producer after it produces a new buffer and is decremented by the consumer after it consumes a buffer.
Producer
item buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
while (true) {
/* Produce an item */
while (((in + 1) % BUFFER_SIZE)== out)
; /* do nothing--no free buffers */
buffer[in] = item;
in = (in + 1) % BUFFER SIZE;
}
Consumer
while (true) {
while (in == out)
; /* do nothing -- nothing to consume */
/* remove an item from buffer */
item = buffer[out];
out = (out + 1) % BUFFER_SIZE;
return item;
}
Producer:
while (true) {
/* produce an item and put in nextProduced */
while (count == BUFFER_SIZE)
; // do nothing
buffer [in] = nextProduced;
in = (in + 1) % BUFFER_SIZE;
count++;
}
Consumer:
while (true) {
while (count == 0)
; // do nothing
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
count--;
/* consume the item in nextConsumed */
}
Race Condition
count++ could be implemented as
register1 = count
register1 = register1 + 1
count = register1
count-- could be implemented as
register2 = count
register2 = register2 - 1
count = register2
Consider this execution interleaving with “count = 5” initially:
S0: producer execute register1 = count {register1 = 5}
S1: producer execute register1 = register1 + 1 {register1 = 6}
S2: consumer execute register2 = count {register2 = 5}
S3: consumer execute register2 = register2 - 1 {register2 = 4}
S4: producer execute count = register1 {count = 6 }
S5: consumer execute count = register2 {count = 4}
6.2The Critical-Section Problem
临界区:一个代码段,在这里进程可以修改共同变量、升级一个表、写一个文件等等。
Solution to Critical-Section Problem
1.Mutual Exclusion - If process Pi is executing in its critical section, then no other processes can be executing in their critical sections
2.Progress - If no process is executing in its critical section and there exist some processes that wish to enter their critical section, then the selection of the processes that will enter the critical section next cannot be postponed indefinitely
3.Bounded Waiting - A bound must exist on the number of times that other processes are allowed to enter their critical sections after a process has made a request to enter its critical section and before that request is granted
-
Assume that each process executes at a nonzero speed
-
No assumption concerning relative speed of the N processes
Algorithm (1) for Process Pi Pj
Pi: do { while (turn != i) ;//entry section critical section turn = j;//exit section remainder section } while (1); |
Pj: do { while (turn != j) ;//entry section critical section turn = i;//exit section remainder section } while (1); |
只能一个进程轮一次
Algorithm (2) for Process Pi Pj
兩個人同時爲true,但是這個幾率比較小
do { flag[i] = TRUE;//entry section while (flag[j]) ;//entry section critical section flag[i] = false; |