Operating system Chapter 2 process management

Written in front: This article refers to the single subject book of the operating system review guide of the Kingway forum

Chapter II process management

Process synchronization

Semaphores are used to achieve synchronization and mutually exclusive access between processes.

Reader writer questions

Model: read and write are mutually exclusive, and write is mutually exclusive; Reading is not mutually exclusive.

Key feature: counter count of mutually exclusive access.

1) Relationship analysis

Writers and anyone are mutually exclusive, and there is no mutually exclusive relationship between readers and readers.

2) Thought arrangement

There are two processes, reader() and writer()

  • Writer: because it is mutually exclusive with any process, only P and V operations can be performed.
  • Reader: mutually exclusive semaphore rw realizes read-write mutual exclusion; In order to realize simultaneous access among readers, a variable count is created to count the number of readers reading shared files. Only the first reader can P(rw); Only the last reader can V(rw); The mutex semaphore mutex is used to access the count variable mutually exclusive for different reader processes
  • Write first
    • Set the mutex semaphore w to control write priority. The read process and write process first P(w) after entering, indicating that they enter when there is no write process, and the write process takes priority.

Use semaphores to realize mutual exclusion and synchronization of processes:

#include<stdio.h>

/* typedef struct{
	int value;
	struct process *L;
}semaphore;
 */
#define semaphore int

semaphore rw = 1; // Reader and writer exclusive access
int count = 0; // Count the number of readers reading shared files
semaphore mutex = 1; // Multiple read processes mutually exclusive access count variable
semaphore w = 1; // Used to implement write first

void writer(){
    while (1){
        P(w); // Enter when there is no write request
        P(rw); //Mutually exclusive access to shared files
        // writing
        R(rw);
        V(w); //Restore access to shared files
    }
    
}

void reader_write_first(){
    while(1){
        P(w); // Enter when there is no write request
        P(mutex);
        if(count == 0)
            P(rw);
        count ++;
        V(mutex);
        V(w); // Restore access to shared files

        // reading

        P(mutex);
        count --;
        if(count == 0)
            V(rw);
        V(mutex);
    }
}

Dining problem of philosophers

A solution to philosopher's problem

Idea 1: at most n-1 philosophers are allowed to eat at the same time

semaphore Max = n - 1;  // A maximum of n -1 people are allowed to eat at the same time
semaphore chopsticks[n];

for(int i = 0; i < n; i ++)
    chopsticks[i] = 1;

Pi(){
    P(Max);
    P(chopsticks[i]); // Take the chopsticks on the left
    P(chopsticks[(i+1)%n]); // Take the chopsticks at your right hand
    //eating
    V(Max);
    V(chopsticks[i]);
    V(chopsticks[(i+1)%n]);
    
    // thinking
}

Exercises

Dining for philosophers: adding bowls (2019 true topic)

Idea: use mutually exclusive semaphores to control philosophers to hold chopsticks. Take the mutually exclusive semaphore bowl and take the minimum value of chopsticks (n) and bowl (m). why?

  • When m < n, the number of bowls is small, and P(bowl) and V(bowl) can play a limiting role. At this time, the number of bowls m is equivalent to Max in the solution of ordinary philosopher's problem, that is, Max = m;

  • When n ≥ m, there are many bowls, and P(bowl) and V(bowl) do not work. The problem degenerates into an ordinary philosopher dining problem, where Max = n - 1;

To sum up, take semaphore bowl = min(m, n- 1);

Semaphore pseudo code:

#include<stdio.h>

/* typedef struct{
	int value;
	struct process *L;
}semaphore;
 */
#define semaphore int
#define n 3
#define m 5

semaphore chopsticks[n];
semaphore bowl = min(n - 1,m);

void Pi(){
    for(int i = 0; i < n; i ++)
		chopsticks[i] = 1; // All mutex semaphores are initialized to 1
	
	P(bowl);
	P(chopsticks[i]);
	P(chopsticks[(i+1)%n]);

	// eating

	V(chopsticks[i]);
	V(chopsticks[(i+1)%n]);
	V(bowl);

	// thinking
}

Both producers and consumers

answer

#include<stdio.h>

/* typedef struct{
	int value;
	struct process *L;
}semaphore;
 */
#define semaphore int
semaphore mutex = 1;// Mutually exclusive access buffer
semaphore full = 0; // Number of buffer products
semaphore empty  = 1; // Number of buffer spaces

//P is the producer
void P(){
    while(1){
        P(empty);
        P(mutex);
        // produce one
        V(mutex);
        V(full);
    }
}

// Q is the consumer
void Q(){
    while(1){
        P(full);
        P(mutex);
        // consume one
        Q(mutex);
        Q(empty);
    }
}

//R is both a producer and a consumer
void R(){
    // Perform the functions of producer
    if(empty == 1){
        P(empty);
        P(mutex);
        // produce one;
        V(mutex);
        V(full);
    }
    //Perform the functions of the consumer
    if(full == 1){
        P(full);
        P(mutex);
        // consume one
        V(mutex);
        V(empty);
    }
}

(producer consumer issues)

Semaphore code

#include<stdio.h>

/* typedef struct{
	int value;
	struct process *L;
}semaphore;
 */
#define semaphore int

semaphore well = 1; //For mutually exclusive access
semaphore vat = 1; // Water tank for mutually exclusive access
semaphore empty = 10; // Indicates the number of barrels of water that can still be contained in the water tank
semaphore full = 0; // Indicates the number of barrels of water in the water tank
semaphore pail = 3; // Indicates how many buckets are available

void old_monk(){

    P(full); // The amount of water in the water tank after the old monk took water--
    P(pail);
    P(vat);
    // Take a bucket of water from the VAT
    V(vat);
    V(empty); // After taking water, the remaining space of the water tank++
    // drink water
    V(pail); 

}
/* 
Pay attention to the sequence of P operation: first confirm that the water tank has spare position, then get the bucket, and then draw water.
 */

void little_monk(){
    P(empty); // Remaining space in water tank-- 
    P(pail);
    P(well);
    // Draw a bucket of water from the well
    V(well);
    P(vat);
    // Pour into the VAT
    V(vat);
    V(full); // Water volume in water tank++
    v(pail);
}

Comments on this topic:

When multiple consecutive P operations are connected together, deadlock may occur during inspection. If P (pay) first, then P(empty); A deadlock will occur. pail is the bucket and empty is the number of buckets of water that can be held in the remaining space in the water tank

Three cooperation processes (synchronization: precursor diagram)

analysis:

Tasks of each process:

  1. P1 process inputs data a from the input device; Then calculate x = a + b; Use the printer to print x,y,z;
  2. P2 process inputs data b from the input device; Then calculate y = a * b;
  3. P3 process inputs data c from the input device; Then calculate z = y + c - a;

Process synchronization:

Note: the use of V before and P after process synchronization, that is, V (a semaphore) after the previous process is executed;, P (a semaphore) before the execution of the subsequent process;

The following is the execution sequence of the three processes, so two synchronization semaphores are required.

This question has the feeling of precursor map. The precursor graph uses semaphores for synchronization, so there is no need to use another mutex semaphore.

deadlock

Deadlock v.s. starvation v.s. loop

  • Deadlock: each process waits for the resources in the other's hand, causing each process to block
  • Hunger: a process cannot move forward without some resources for a long time. For example, in the short process first (SPF) algorithm, long processes may not run all the time, "hungry"
  • Dead loop: the phenomenon that a process cannot jump out of a loop during execution

Deadlock and starvation are the problems to be solved by the operating system, and deadlock is the problem to be solved by the application programmer.

Deadlock prevention

Deadlock avoidance (banker algorithm)

Deadlock detection and release

The system does not take any measures when allocating resources to the process, but provides deadlock detection and release means in the specific allocation process.

Resource allocation graph: it is a directed graph used to represent the relationship between system resources and processes at a certain time.

The circle represents the process, the box represents a kind of resources, and the number of circles in the box represents the number of such resources.

Knowledge structure of deadlock

Tags: Linux Windows Operating System

Posted on Sat, 18 Sep 2021 07:23:31 -0400 by SQL Advanced