Semaphore and Deadlock in Computer Operating System

Table of contents

Semaphore mechanism

Foreword:

Semaphore meaning

shaping semaphore

record semaphore

Semaphore realizes process mutual exclusion

Specific process

Semaphore mechanism realizes process synchronization

Implementation process

Semaphore implements predecessor relationship

Implementation process

producer consumer problem

Concrete operation

Change the operation order of empty and mutexPV

Multiple Producer-Multiple Consumer Problem

analyze

implement 

smoker problem

reader problem

dining philosophers problem

Monitor

Why introduce the pipeline

Definition and basic characteristics of monitor

The basic characteristics of the tube

deadlock

Necessary conditions for deadlock

Specific case 

deadlock handling strategy

deadlock prevention

break the mutex condition

breach of the inalienable condition

Undermining the Inalienable Conditions Program

shortcoming

Destroy requests and hold conditions

break loop wait condition

avoid deadlock

Deadlock detection and resolution

Deadlock detection and resolution algorithm

deadlock detection

Method to remove deadlock

Semaphore mechanism

Foreword:

  • In the double flag check first method, the "check" and "lock" operations of entering the area cannot be completed in one go, which leads to the situation that two processes may enter the critical area at the same time
  • All implementations of process mutual exclusion cannot realize the right to wait
  • In 1965, Dutch scholar DiJkstra proposed an effective method for realizing mutual exclusion and synchronization of processes - the semaphore mechanism

Semaphore meaning

Semaphore: A semaphore is actually a variable (it can be an integer or a more complex record variable). A semaphore can be used to represent the number of certain resources in the system. For example, there is only one printer in the system. You can set a semaphore with an initial value of 1

Notice:

  • The user process can operate on the semaphore by using a pair of primitives provided by the operating system, thereby conveniently realizing the mutual exclusion of the process and the synchronization of the process
  • A pair of primitives: wait(S) primitive and signal(S) primitive, the primitive can be understood as a function written by ourselves, the function names are wait and signal respectively, the semaphore S in the brackets is actually a function call A parameter passed in (we can use a pair of primitives provided by the system to operate on the semaphore)
  • The wait and signal primitives are referred to as P and V operations for short. Therefore, the two operations of wait(S) and signal(S) are often written as P(S) and V(S); a P operation on the semaphore S means that the process requests a unit of this type of resource, and a P operation on the semaphore S Performing a V operation means that the process releases a unit of this type of resource

shaping semaphore

Meaning: use an integer semaphore to represent the number of certain resources in the system

eg: a computer has a printer

Understanding: When a thread executes, wait(S) is executed first. At this time, if another thread comes in, because S<=0 is true, it will continue to loop; until the process just finished executing signal(S) releases the semaphore

Note: If a process (P1) cannot enter the critical area temporarily, if the system resources are not enough, the processor will be occupied all the time, and the continuous check will cause busy waiting, which is not satisfied with the right to wait

record semaphore

Preface: In order to solve the problem of busy waiting for plastic semaphores

Meaning: a semaphore represented by a record data structure

Understanding: When a thread executes, wait(S) is executed first. If another thread comes in at this time, if the number of remaining resources is <0, the process will enter the blocking state from the running state (occupying a semaphore before blocking), and hang it Go to the waiting queue L of the semaphore S; the process will not be awakened until the previous process executes the signal(S) and releases the semaphore.

Semaphore realizes process mutual exclusion

Specific process

  1. Analyze key activities of concurrent processes and delineate critical sections
  2. Set the mutual exclusion semaphore mutex, the initial value is 1 (because only one resource can be accessed in the critical section)
  3. Execute P(mutex) before the critical section
  4. Execute V(mutex) after the critical section

Notice:

  • Different semaphores need to be set for different critical resources;
  • P and V operations must occur at the same time; lack of P will not guarantee mutual exclusive access to critical resources, and lack of V will cause resources to never be released, and the waiting process will not be woken up

Semaphore mechanism realizes process synchronization

Process synchronization: to make each concurrent process progress in an orderly manner as required

Implementation process

  1. Analyze where the "synchronization relationship" needs to be realized, that is, it is necessary to ensure that two operations are performed in tandem
  2. Set the synchronization semaphore S, the initial value is 0
  3. Execute V(S) after the previous operation
  4. Execute P(S) before the post operation

Understanding: If you want code 2 to be executed before code 4, because the initial semaphore is 0, first execute the V operation to change the semaphore to 1, and then execute the P operation to change the semaphore to 0 before executing the next piece of code (because S= 0, so it is impossible to execute P operation first; if P is executed first, it will be blocked directly, and it will be woken up after V operation is executed)

Semaphore implements predecessor relationship

Implementation process

  1. To set a synchronization variable for each pair of predecessor relations
  2. The corresponding synchronization variable performs the V operation after the "pre-operation"
  3. The corresponding synchronization variable performs the P operation before the "post operation"

Understanding: It is equivalent to a multi-layer synchronization relationship.

producer consumer problem

Concrete operation

Preface: There are a group of producer processes and a group of consumer processes in the system. The producer process produces one product each time and puts it into the buffer, and the consumer process takes out one product from the buffer each time and uses it (note: the product here is understood as Some kind of data) producers and consumers share an initially empty buffer of size n

Notice:

  • Only when the buffer is not full, the producer can put the product into the buffer, otherwise it must wait (synchronous relationship)
  • When the buffer is not empty, the consumer can take out the product from it, otherwise it must wait (synchronous relationship)
  • The buffer is a critical resource, and each process must have mutually exclusive access (mutual exclusion relationship)

Change the operation order of empty and mutexPV

Understanding: If the buffer is full of products at this time, empty=0, full=n; then the producer produces products, 1 locks up, and then finds that the 2 buffer is gone and cannot enter the buffer, it will always be blocked; when it comes to the consumer , because P has been locked and has not been released, so you can’t get in directly (producers need V(empty), consumers need P(mutex)—waiting for each other’s resources, deadlock)

Conclusion: The P operation that implements mutual exclusion must be after the P operation that implements synchronization, so that deadlock will not occur

Multiple Producer-Multiple Consumer Problem

Example: There is a plate on the table, and only one fruit can be placed at a time; father puts apples for daughter to eat; mother puts oranges for son, only when the plate is empty can fruit be placed; only when there is something on the plate that you need of fruits are only consumed by sons and daughters

analyze

Mutual exclusion relationship (mutex=1): access to the buffer must be mutually exclusive

Synchronization relationship (one before one after)

  • Father puts apples, daughter takes
  • Mom puts oranges, son takes them
  • Parents can put fruit only if the plate is empty

implement 

Note: P(mutex) and V(mutex) can be omitted here (because there is only one plate, the father consumes it, and the mother naturally cannot consume it [omit the P(mutex) operation]; and father and daughter, mother and son are Synchronization relation [omit V(mutex) operation])

smoker problem

Suppose there is a system with three smoker processes and one supplier process. Each smoker keeps rolling cigarettes and smoking him, but rolling and smoking a cigarette requires three materials: tobacco, paper, and glue. Of the three smokers, the first owns tobacco, the second owns paper, and the third owns glue. The supplier process provides three materials indefinitely, the supplier puts two materials on the table each time, the smoker who has the remaining material rolls a cigarette and smokes it, and sends a signal to the supplier process to tell it Finished, the supplier will put another two materials on the table, this process has been repeated (supplier purpose: smokers take turns to smoke)

three combinations

  • Combination 1: paper + glue
  • Combination 2: Tobacco + Glue
  • Combination Three: Tobacco + Paper

synchronization relationship

  • There is combination 1 on the table: the first smoker takes it
  • Combo 2 on the table: the second smoker takes
  • Combo 3 on the table: the third smoker takes it
  • Signal done: the supplier puts the next combination on the table

reader problem

Preface: There are two concurrent processes of readers and writers sharing a file. When two or more reading processes access the shared data at the same time, no side effects will occur, but if a writing process and other processes access the shared data at the same time Circumstances that may lead to data inconsistencies

therefore require

  1. Allow multiple readers to perform read operations on the file at the same time
  2. Only one writer is allowed to write information to the file
  3. Any writer does not allow other readers or writers to work until the write operation is complete
  4. Before the writer executes the write operation, all existing readers and writers should exit

Potential problem: As long as the reading process is still reading, the writing process has to block and wait, and may "starve to death". Therefore, the read process is prioritized in this algorithm

Understanding: When a reader process reads a file, a new writer process arrives. Since the first reader process has already executed V(w), the writer process will not be blocked when it executes the P(w) operation; When performing the P(rw) operation, since the first reader process has already performed the P operation on P(rw), the writer process will be blocked at this position; if a second reader process arrives at this time, due to the previous The writer process P(w), does not execute V(w), so the reader process will be blocked at P(w)

Core idea: Set a counter count to record the number of reading processes currently accessing the shared file; you can use the count value to judge whether the currently entering process is the first/last reading process, and make different treatments

dining philosophers problem

There are five philosophers sitting on a round table, a chopstick is placed on the table between every two philosophers, and a bowl of rice is in the middle of the table. Philosophers devote their lives to thinking and eating, and philosophers do not affect other people when they think. Only when the philosopher is hungry, he tries to pick up the left and right chopsticks (one by one). If the chopsticks are already in the hands of others, he needs to wait. A hungry philosopher can only start eating by picking up two chopsticks. When the meal is finished, put down the chopsticks and continue thinking

Preface: semaphore setting, define the mutually exclusive semaphore array chopstick[5] ={1,1,1,1,1} is used to realize the mutually exclusive access to 5 chopsticks, and the philosophers are numbered 0-4, The chopsticks on the left of philosopher i are numbered i, and the chopsticks on the right are numbered (i+1)%5

Key issues: Solve deadlocks, add mutual exclusion semaphore mutex

Monitor

Why introduce the pipeline

Problems with the semaphore mechanism: programming is difficult and error-prone

Definition and basic characteristics of monitor

A monitor is a special software module that consists of these parts

  1. Shared data structures local to the monitor
  2. A set of procedures that operate on the data structure
  3. A statement that sets an initial value for shared data local to the monitor
  4. A monitor must have a name

The basic characteristics of the tube

  1. Data local to the monitor can only be accessed by processes local to the monitor
  2. A process can enter the monitor to access shared data only by calling the process in the monitor
  3. Only one process is allowed to execute an internal procedure in the monitor at a time

Understanding: If the two consumers execute first, the producer process executes later; then the first consumer process will call the remove method of the monitor when it is executed, and first determine whether there are products available in the buffer at this time, if not, then It will wait in the queue related to the empty condition variable; similarly, when the second consumer process starts to execute remove, it will also find that the value of count is 0, and it will also wait for the end of the empty queue; after that, there will be a producer process Start to execute the insert function, which will put its own product into the buffer, and check whether the product it puts in is the first product in the buffer. If it is the first product, it means that there may be other consumer processes I am waiting for my product, so I will wake up the process in the empty queue. After the first process is woken up, it will start to execute count--, and then check whether the buffer is full before taking the product. If the buffer is full, it means It means that there may be a producer process that needs to be awakened by signal(full), and then return the product pointer to take out the product;

Notice:

  • The feature that each process must mutually exclusive access to the monitor is implemented by the compiler
  • Condition variables and wait/wake operations can be set in the monitor to solve synchronization problems

deadlock

Meaning: Two threads hold the resources needed by each other, wait for each other's execution results, form a stalemate, and neither thread will release their resources

Starvation: A condition in which a process cannot move forward due to a prolonged lack of access to desired resources

Necessary conditions for deadlock

  • Mutual exclusion conditions: Only contention for resources that must be mutually exclusive can cause deadlock
  • Request and hold conditions: a process blocks on requesting resources and holds on to acquired resources
  • Non-alienable condition: The process has obtained the resource and cannot be deprived until it is used up
  • Loop waiting condition: A head-to-tail loop waiting resource relationship is formed between several processes

Notice:

  1. When a deadlock occurs, there must be a circular wait, but when a circular wait occurs, there may not be a deadlock
  2. Unreasonable allocation of inalienable resources can lead to deadlock

Specific case 

public class DeadLock {
    public static void main(String[] args) {
        Makeup g1 = new Makeup(0, "灰姑娘");
        Makeup g2 = new Makeup(1, "白雪公主");
        g1.start();
        g2.start();
    }
}
class Lipstick{}
class Mirror{}
class Makeup extends Thread{
    //需要的资源只有一份
    static Lipstick lipstick=new Lipstick();
    static Mirror mirror=new Mirror();
    int choice;
    String girlName;
    Makeup(int choice,String girlName){
        this.choice=choice;
        this.girlName=girlName;
    }
    @Override
    public void run() {
        //化妆
        try {
            makeup();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    private void makeup() throws InterruptedException {
        if (choice==0){
            synchronized (lipstick){
                System.out.println(this.girlName+"获得口红的锁");
                Thread.sleep(1000);
                synchronized (mirror){
                    System.out.println(this.girlName+"获得镜子的锁");
                }
            }
        }else {
            synchronized (mirror){
                System.out.println(this.girlName+"获得镜子的锁");
                synchronized (lipstick){
                    System.out.println(this.girlName+"获得口红的锁");
                }
            }
        }
    }
}

deadlock handling strategy

  1. To prevent deadlock, destroy one or more of the four necessary conditions for deadlock
  2. Avoid deadlocks, prevent the system from entering an unsafe state in some way, thereby avoiding deadlocks
  3. The detection and removal of deadlocks allow deadlocks to occur, but the operating system will be responsible for detecting the occurrence of deadlocks, and then take some measures to remove deadlocks

deadlock prevention

break the mutex condition

Mutual exclusion conditions: Only contention for resources that must be mutually exclusive can cause deadlock

If the resources that can only be used mutually exclusive are changed to allow shared use, the system will not enter a deadlock state.

For example, SPOOLing technology, the operating system can use SPOOLing technology to logically transform the exclusive device into a shared device, as shown in the following example

Process: The requests sent by each process to the printer will be received by the output process first, and when their requests are received, these processes can smoothly execute other things; then the output process will be based on the requests of each process, Put it on the printer to print out

Disadvantages: Not all resources can be transformed into resources for shared use. And for the sake of system security, this kind of mutual exclusion must be protected in many places, so the mutual exclusion condition cannot be broken in many cases

breach of the inalienable condition

Non-alienable condition: Before the resources obtained by the process are used up, they cannot be forcibly taken away by other processes, but can only be actively released

Undermining the Inalienable Conditions Program

  • Scenario 1: When a process requests new resources and cannot be satisfied, he (the process) must immediately release all the resources held, and apply again when needed in the future. That is, even if some resources are not used up, they need to be actively released, thus breaking the inalienable condition
  • Solution 2: When the resources needed by a certain process are occupied by other processes, the operating system can assist to forcibly deprive the desired resources. This method generally needs to consider the priority of each process (such as the deprivation scheduling method, which is to forcibly deprive processor resources to processes with higher priority)

shortcoming

  • more complicated to implement
  • The resources obtained by releasing may invalidate the work of the previous stage, so this method is generally only suitable for resources that are easy to save and restore state, such as CPU
  • Repeated application and release of resources will increase system overhead and reduce system throughput
  • If Option 1 is adopted, it means that as long as a certain resource is not available temporarily, those resources obtained before need to be given up and re-applied later. If this happens all the time, it will lead to process starvation

Destroy requests and hold conditions

Request and hold conditions: a process blocks on requesting resources and holds on to acquired resources

The static allocation method can be used, that is, the process applies for all the resources it needs before running, and it will not be put into operation until the resources are not satisfied. Once put into operation, these resources are always owned by him, and the process will not request any other resources

Disadvantages: Some resources may only take a short time, so if the process keeps all the resources throughout the process (some resources are not used frequently), it will cause serious waste of resources, and the resource utilization rate is extremely low. In addition, this strategy may also cause some processes to starve

break loop wait condition

Circular waiting condition: There is a circular waiting chain of process resources, and the resources obtained by each process in the chain are simultaneously requested by the next process

Sequential resource allocation can be used. First number the resources in the system, and stipulate that the process must request resources in the order of increasing number, and the resources of the same type (resources with the same number) can be applied for at one time

Principle: A process is only eligible to apply for a resource with a large number if it already occupies a resource with a small number. According to this rule, it is impossible for a resource process that already holds a large number to come back and apply for a resource with a small number in reverse, so that there will be no circular waiting

avoid deadlock

Safe sequence: If the system allocates resources according to this sequence, each process can be completed. As long as a safe sequence can be found, the system is in a safe state. Of course, security sequences may have multiple

The core idea of ​​the banker's algorithm: Before resource allocation, pre-judge whether the allocation will cause the system to enter an unsafe state, so as to decide whether to agree to the resource allocation request (if it will enter an unsafe state, temporarily reject this request, Let the process block and wait first)

Example: There are 5 processes P0-P4 in the system, 3 kinds of resources R0-R2, and the initial quantity is (10, 5, 7), then the situation at a certain moment can be expressed

Notice:

  1. At this time, a total of (7, 2, 5) is allocated and (3, 3, 2) is left
  2. Check in turn whether the remaining available resources (3, 3, 2) meet the needs of each process
  3. Allocate the remaining available resources to the process that can complete the task. When the process is executed, the resources will be released, so that the system can be in a safer state (try to find a process that needs to borrow less and can return more resources after completing the task)
  4. Safe sequence assignment: {P1, P3, P0, P2, P4} (just one, there may be many)

The steps of the banker's algorithm

  1. Check if this application exceeds the previously declared maximum number of needs
  2. Check whether the remaining available resources of the system can still satisfy this request at this time
  3. try to allocate, change the data structure
  4. Use the security algorithm to check whether this allocation will cause the system to enter an unsafe state 

Security Algorithm Steps

  1. Check whether the current remaining available resources meet the maximum demand of a process, if yes, add the process to the security sequence and reclaim all the resources held by the process
  2. Repeat this process continuously to see if all processes can be added to the security sequence in the end

Deadlock detection and resolution

Deadlock detection and resolution algorithm

  • Deadlock detection algorithm: used to detect system status to determine whether deadlock occurs in the system
  • Deadlock release algorithm: When it is determined that a deadlock has occurred in the system, this algorithm can be used to free the system from the deadlock state

In order to detect whether a deadlock has occurred in the system

  • Use some kind of data structure to save resource request and allocation information
  • Provide an algorithm that uses the above information to detect whether the system has entered a deadlock state

deadlock detection

After the process has requested the required resources, it will release all resources and will not apply for resources. If all edges can be finally eliminated according to this method, the graph is said to be completely simplified. At this time, there must be no deadlock (equivalent to finding a safe sequence); if all the edges cannot be eliminated in the end, then a deadlock occurs at this time (the process that is still connected to the edge is in a deadlock)

Method to remove deadlock

  1. Resource deprivation method: suspend (temporarily put on external memory) some deadlock process, seize its resources, and allocate these resources to other deadlock processes. But it should prevent the suspended process from starvation due to lack of resources for a long time
  2. Cancellation process method: force cancellation of some or even all deadlocked processes, and deprive these processes of resources. The advantage of this approach is that it is simple to implement, but the price paid may be high. Because some processes may have been running for a long time and are close to the end. Once they are terminated, it can be said that they will fall short and need to start all over again.
  3. Process rollback method: let one or more deadlock processes roll back enough to avoid deadlock, which requires the system to record the historical information of the process and set the restore point

Guess you like

Origin blog.csdn.net/m0_60027772/article/details/129596293