操作系统——Process Synchronization 进程同步

目录​​​​​​​

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 哲学家进餐问题


1. Background 背景

1.1 What is Process Synchronization? 什么是进程同步

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. 两个进程不能同时访问共享资源。

1.2 Race condition 竞争条件

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. 为了防止竞争,必须同步并发的进程

1.3 Syncronization 同步

同步发生在协作进程之间,基础思想是需要一个任何形式的锁。


2. The Critical-Section Problem 临界区问题

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:

操作系统——Process Synchronization 进程同步_第1张图片

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.

  1. 启用这个请求的代码段叫做entry section
  2. entry section 后面会有exit section
  3. entry和exit中间的进程代码段叫做critical section
  4. 剩下的代码叫做remainder section

Race condition updating a variable

操作系统——Process Synchronization 进程同步_第2张图片

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 (临界区的三个原则)

  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 some processes wish to enter their critical sections, then only those processes that are not executing in their remainder sections can participate in deciding which will enter its critical section next, and this selection cannot be postponed indefifinitely. 如果没有进程在临界区,其他进程应该被允许进入临界区。
  3. Bounded waiting. 有效等待 There exists a bound, or limit, 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. 进程做出进入临界区请求后,其他进程进入临界区的次数是有上限的,进程发出请求后等待允许的时间有限。

Types of solutions to CS problem

  1. Software solutions: algorithms whose correctness relies only on the assumption that only one process/thread at a time can access a memory location/resource.
  2. Hardware solutions: rely on special machine instructions for “locking”.
  3. Operating System and Programming Language solutions (e.g. Java): provide specific functions and data structures for the programmer to use for synchronization.

Two general approaches are used to handle critical sections in operating systems (处理临界区的两种内核)

  1. Preemptive kernels. 抢占式:A preemptive kernel allows a process to be preempted while it is running in kernel mode. 允许进程在内核模式下运行时被抢占。
  2. Nonpreemptive kernels. 非抢占式:nonpreemptive kernel does not allow a process running in kernel mode to be preempted. 进程在内核模式运行时不会被抢占。不会产生竞争。

3. Solutions for critical-section problem 临界区问题解决办法

每个方法都要遵循互斥,前进,有限等待三个原则

3.1 Software Solutions

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)

3.1.1 Peterson's Solution

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

  1. In the entry section, process P0 first raises a flag indicating a desire to enter the critical section. 进程P0首先引发一个标志,表示希望进入临界区。
  2. Then turn is set to 1 to allow the other process to enter their critical section if process P1 so desires. 然后,turn被设置为1,如果进程P1希望,则允许其他进程进入临界区。
  3. The while loop is a busy loop, which makes process P0 wait as long as process P1 has the turn and wants to enter the critical section. 只要过程P1有turn并且想要进入临界区,P0就应该等待
  4. Process P0 lowers the flag[0] in the exit section, allowing process P1 to continue if it has been waiting. 进程P0降低exit section中的标志[0],允许进程P1继续(如果P1一直在等待)。

Drawbacks of Software Solutions

  • ​​​​​​​Complicated to program.
  • Busy waiting (wasted CPU cycles).
  • It would be more efficient to block processes that are waiting (just as if they had requested I/O). This suggests implementing the permission/waiting function in the Operating System.
  • But first, let’s look at some hardware approaches.

3.2 Hardware 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

  • Lock value = 0 means the critical section is currently vacant and no process is present inside it.
  • Lock value = 1 means the critical section is currently occupied and a process is present inside it.

满足互斥的需求,但是不能保证有效等待。

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

  • Applicable to any number of processes on either a single processor or multiple processors sharing main memory.
  • Simple and easy to verify.
  • It can be used to support multiple critical sections; each critical section can be defined by its own variable. 它可以用来支持多个临界区;每个临界区可以由它自己的变量定义。

Disadvantages of hardware solution

  • Busy-waiting is employed, thus while a process is waiting for access to a critical section it continues to consume processor time.
  • Starvation is possible when a process leaves a critical section, and more than one process is waiting. 
  • Deadlock is possible if a low priority process has the critical region and a higher priority process needs, the higher priority process will obtain the processor to wait for the critical region. 

3.3 Mutex locks / Mutual exclusion 互斥锁

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;
}

操作系统——Process Synchronization 进程同步_第3张图片

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. 

何谓自旋锁?它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。

3.4 Semaphore 信号量

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

  • For n processes
  • Initialize semaphore S to 1
  • Then only one process is allowed into CS (mutual exclusion)
  • To allow k processes into CS at a time, simply initialize mutex to k 简单的将互斥对象初始化为k

There are two main types of semaphores:

  1. COUNTING SEMAPHORE – allow an arbitrary resource count. Its value can range over an unrestricted domain. It is used to control access to a resource that has multiple instances.  计数信号量  信号量S被初始化为可用资源的数量,函数wait()和signal()定义不变,S代表着当时剩余的可用资源的数量。
  2. BINARY SEMAPHORE – This is also known as mutex lock. It can have only two values: 0 and 1. Its value is initialized to 1. It is used to implement the solution of critical section problem with multiple processes. 二进制信号量  也被称为互斥锁Mutex,值只有1和0,初始化为1,函数wait()和signal()分别在值为1和0的情况下被合法调用。

Operating systems often distinguish between counting and binary semaphores.

Same issues of semaphore

  • Starvation and Deadlock are situations that occur when the processes that require a resource are delayed for a long time.
  • 死锁Deadlock 每个进程都持有一定的资源,又希望获得正在被其他进程占有的资源,这样每个进程都得不到完整资源。
  • 饥饿Starvation 进程始终得不到它想要获得的资源。

4. Classical Problems of Synchronization 同步的经典问题

4.1 The Bounded-Buffer / Producer-Consumer Problem 有限缓冲问题

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.

  • the semaphore empty is initialized to the value n.
  • the semaphore full is initialized to the value 0.

操作系统——Process Synchronization 进程同步_第4张图片

4.2 The Readers–Writers Problem  读者-写者问题

A data set is shared among a number of concurrent processes.

  • Only one single writer can access the shared data at the same time, any other writers or readers must be blocked.
  • Allow multiple readers to read at the same time, any writers must be blocked.

Solution: Acquiring a reader–writer lock requires specifying the mode of the lock: either read or write access.

4.3 The Dining-Philosophers Problem 哲学家进餐问题

How to allocate several resources among several processes. 

Several solutions are possible:

  • Allow only 4 philosophers to be hungry at a time.
  • Allow pickup only if both chopsticks are available. ( Done in critical section )
  • Odd # philosopher always picks up left chopstick 1 st ,
  • Even # philosopher always picks up right chopstick 1 st .

操作系统——Process Synchronization 进程同步_第5张图片

课堂笔记,整理不易,有失偏颇的地方还请大佬们指正

这位学长老哥对问题描述的比较清楚,可以参考这篇笔记CPT104 计算机操作系统概念笔记

你可能感兴趣的:(Operating,System,windows,开发语言,算法)