目录
1. Background 背景
1.1 What is Process Synchronization? 什么是进程同步
1.2 Race condition 竞争条件
1.3 Syncronization 同步
2. The Critical-Section Problem 临界区问题
3. Solutions for critical-section problem 临界区问题解决办法
3.1 Software Solutions
3.1.1 Peterson's Solution
3.2 Hardware Solutions
3.3 Mutex locks / Mutual exclusion 互斥锁
3.4 Semaphore 信号量
4. Classical Problems of Synchronization 同步的经典问题
4.1 The Bounded-Buffer / Producer-Consumer Problem 有限缓冲问题
4.2 The Readers–Writers Problem 读者-写者问题
4.3 The Dining-Philosophers Problem 哲学家进餐问题
PS is the task of coordinating the execution of processes in a way that no two processes can have access to the same shared data and resources. 两个进程不能同时访问共享资源。
Concurrent access to shared data may result in data inconsistency. Maintaining data consistency requires mechanisms to ensure the orderly execution of cooperating processes. 对共享数据的并发访问可能导致数据的不一致。
Race condition: The situation where several processes access and manipulate shared data concurrently. The final value of the shared data depends upon which process finishes last. 指的是几个进程并发访问和操作共享数据。共享数据的最终值取决于哪个进程最后完成。
To prevent race conditions, concurrent processes must be synchronized. 为了防止竞争,必须同步并发的进程
同步发生在协作进程之间,基础思想是需要一个任何形式的锁。
Each (concurrent) process has a code segment, called Critical Section (CS), in which the shared data is accessed. When using critical sections, the code can be broken down into the following sections:
The critical-section problem is to design a protocol that the processes can use to cooperate. Each process must request permission to enter its critical section.
Race condition updating a variable
Critical section to prevent a race condition
Multiprogramming allows logical parallelism, uses devices efficiently but we lose correctness when there is a race condition. So, we forbid/deny logical parallelism inside critical section, so we lose some parallelism, but we regain correctness.
A solution to the critical-section problem must satisfy the following three requirements (临界区的三个原则)
Types of solutions to CS problem
Two general approaches are used to handle critical sections in operating systems (处理临界区的两种内核)
每个方法都要遵循互斥,前进,有限等待三个原则
Framework for analysis of solutions
Each process executes at nonzero speed but no assumption on the relative speed of n processes. No assumptions about order of interleaved execution. The central problem is to design the entry and exit sections. General structure of a process:
do {
entry section
critical section - CS
exit section
remainder section - RS
} while(TRUE)
Only 2 processes, P0 and P1. It was formulated by Gary L. Peterson in 1981. Processes may share some common variables to synchronize their actions.
int turn; //indicates whose turn it is to enter the critical section.
boolean flag[2]; // initialized to FALSE,
// indicates when a process wants to enter into their CS.
// flag[i] = true implies that process Pi is ready (i = 0,1)
NEED BOTH the turn and flag[2] to guarantee Mutual Exclusion, Bounded waiting, and Progress. turn表示下一张门票;flag表明现在谁在内。这一次要进去之前把自己flag设为true表示我要进去,然后把下一次进去的机会turn留给对面,对面flag是true则自己不被允许进入临界区,只有这次机会在自己这里并且对面falg为flase自己才能进去。
//Initialization
boolean flag[2];
int turn;
flag[0] = false;
flag[1] = false;
turn = 0;
//or turn = 1;
//Processs P0
do{
flag[0] = true;
turn = 1;
while(flag[1] && turn == 1);
//critical section
flag[0] = false;
//remainder section
} while(true);
//Process P1
do{
flag[1] = true;
turn = 0;
while(flag[0] && turn == 0);
//critical section
flag[1] = false;
//remainder section
} while(true);
Explanation of Peterson's algorithm
Drawbacks of Software Solutions
Single-processor environment 单处理器环境——可以禁用中断
Effectively stops scheduling other processes. Currently running code would execute without preemption. 有效地停止调度其他进程。当前运行的代码将在没有抢占的情况下执行。
临界区有全局变量lock,只有lock为F时才进入,进入时检查是否为F,申请到了后置为T,退出时置为F
Test and set solution: Initially, lock value is set to 0
满足互斥的需求,但是不能保证有效等待。
boolean lock;
boolean test_and_set(boolean *target) {
boolean rv = *target;
*target = true;
return rv;
}
test_and_set(&lock);
do{
while(test_and_set(&lock));
/* do nothing */
/* critical section */
lock = false;
/* remainder section */
} while(true);
Multi-processor environment 多处理器环境 —— 不可中断的
Modern machines provide special atomic hardware instructions. Atomic mean non-interruptable (i.e., the instruction executes as one unit).
A global variable lock is initialized to 0. The only Pi that can enter CS is the one which finds lock=0. This Pi excludes all other Pj by setting lock to 1.
全局变量lock,只有lock为0时才进入,申请成功后交换(0,1)状态,退出时置为0,适用于多处理器环境。
int compare_and_swap(int *value, int expected, int new value) {
int temp = *value;
if (*value == expected)
*value = new value;
return temp;
}
int lock;
compare_and_swap(&lock,0,1);
do {
while (compare_and_swap(&lock, 0, 1) != 0);
/* do nothing */
/* critical section */
lock = 0;
/* remainder section */
} while (true);
Advantages of hardware solution
Disadvantages of hardware solution
The simplest of tool is the Mutex lock. Mutex is a software tool. Mutex allow multiple process / thread to access a single resource but not simultaneously. 基于软件,允许多个程序线程 不同时地 访问同个资源。
To enforce mutex at the kernel level and prevent the corruption of shared data structures - disable interrupts for the smallest number of instructions is the best way. 为最小的指令数禁用中断是最好的方法。
To enforce mutex in the software areas – use the busy-wait mechanism. Busy-wait mechanism or busy-looping or spinning is a technique in which a process/thread repeatedly checks to see if a lock is available. 在这种技术中,进程/线程重复检查锁是否可用。
Using mutexes is to acquire a lock prior to entering a critical section, and to release it when exiting.
Mutex object is locked or unlocked by the process requesting or releasing the resource. 通过进程需要资源或释放资源来锁住或解锁互斥对象。
acquire() {
while (!available);
/* busy wait */
available = false;
}
release() {
available = true;
}
自旋锁 spinlock
This type of mutex lock is called a spinlock because the process “spins” while waiting for the lock to become available.
何谓自旋锁?它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。
A semaphore S is an integer variable. Semaphore is accessed only through two standard atomic operations: wait() and signal().
The definition of wait() is as follows:
int S; //Semaphore
wait(S) {
while (S <= 0);
// busy wait
S--;
}
The definition of signal() is as follows:
int S; //semaphore
signal(S) {
S++;
}
Using semaphore for solving CS problem
There are two main types of semaphores:
Operating systems often distinguish between counting and binary semaphores.
Same issues of semaphore
In our problem, the producer and consumer processes share the following data structures:
int n;
semaphore mutex = 1;
semaphore empty = n;
semaphore full = 0;
The empty and full semaphores count the number of empty and full buffers.
A data set is shared among a number of concurrent processes.
Solution: Acquiring a reader–writer lock requires specifying the mode of the lock: either read or write access.
How to allocate several resources among several processes.
Several solutions are possible:
课堂笔记,整理不易,有失偏颇的地方还请大佬们指正
这位学长老哥对问题描述的比较清楚,可以参考这篇笔记CPT104 计算机操作系统概念笔记