Operating system-Process communication __ Operating system

Source: Internet
Author: User
Tags message queue mutex semaphore

The difficulty in process communication is the mutex access to the critical section, let's take a look at a busy waiting mutex

Lock Variable

In fact, the solution we can easily think of is the addition of locks,

int lock,cnt;
void Solve_fork ()
{while
    (lock==1);
    lock = 1;
    cnt++;  
    printf ("%d has entered the critical section \ n", Getpid ());
    lock = 0;
}

At the same time we can easily find that this is problematic, two processes at the same time to determine lock, and then all lock, and then enter the critical section, in fact, with the above code test found that, basically many times will also access the critical area. Of course, the solution is very simple, that is, let judgment and lock into an atomic operation, such as the signal to be said later or with hardware lock, hardware lock similar to the switch we use, can be implemented with registers, completely feasible.

Strict rotation method (spin lock)
This is actually an improvement to the above problem of locking, the principle of which is to wait for a different value every two processes.

int lock,cnt;
void Solve_fork1 ()
{while
    (lock==1) {}
    cnt++;
    printf ("%d has entered the critical section \ n", Getpid ());
    lock = 1;
}
void Solve_fork2 ()
{while
    (lock = = 0) {}
    cnt++;
    printf ("%d has entered the critical section \ n", Getpid ());
    lock = 0;
}

The above is achieved mutex access is not wrong, but also problematic, first of all, he was busy to solve the problem, and secondly, he can solve two of the process of competition.

Peterson Solution
The result of the solution is similar to the above, but the thought is different. Can study

const int N = 2;
int lock;
int inter[n];

void enter_region (int pro)//incoming parameter 0/1
{
    int other;
    other = 1-pro;
    Inter[pro] = 1;
    lock = Pro;
    while (lock = = Pro && Inter[other] = = 1);
}
void leave_region (int pro)
{
    Inter[pro] = 0;
}
not busy waiting for mutexes

Signal Volume

This should be the most common, the principle of the lock variable said, which is to turn him into an atomic operation, but how to become an atomic operation, the operating system inside how to achieve this atomic operation.
In fact, the methods described above are available, just to solve the busy situation, here is an operating system to achieve the situation, for multi-core, the operating system uses TSL instructions to achieve atomic operation, instructions for TSL RX Lock, that is, the value of the lock copy to the RX register, The CPU that executes the TSL instruction will lock the memory bus. Prevents other CPUs from accessing the command before the end of this instruction. is actually understood as the above said switch.
There is also a problem here is busy and so on, this can use sleep and wakeup primitive language to solve. Activates the current process with the wakeup primitive when another access is complete.
Of course, in addition to the signal volume and the concept of mutual-exclusion signal, is not counted, only 0 or 1 of the signal volume

Piping Program

This linux used words should not be difficult to understand, is the Linux above ' | ' symbol, can be understood as a pipe, we put the data generated by a process as another often need to input data, and then through a pipeline to the second process, the implementation of Linux above is to open a pipe, while closing the read, the other side off write, and then communicate on OK.

shared storage

In fact, to two processes to open a shared storage space that can be accessed at the same time, and then alternate access can be achieved, open the shared system calls, respectively, to open and close the shared storage space
Shmget (key_t key, size_t size, int flag)
Shmdt (void *addr)

Message Queuing
Write the field that you want to communicate to the message queue, and then another process that you want to use to get the classic IPC problem in the message queue

The question of dining philosophers
5 Philosophers to eat, a total of five chopsticks in a round table, philosophers most of the time thinking, hungry will eat, and then how to design a program to make it not hungry and efficient meals.
First look at what happens if every philosopher is hungry and free to take chopsticks to eat. If they first take the chopsticks to the left, and then take the right, so add 5 people at the same time hungry, and then to get to the left of the chopsticks, and then success, all go to the right chopsticks, are not successful, so that the deadlock, there is no political reform went on.
A very intuitive solution is that if you take the left chopsticks to take the right chopsticks can not take, put down the chopsticks, to wait for a random number, and then go to take, so that the first can be resolved without deadlock, but because it is a random number, the result is not controllable, so the performance is not good enough.
In fact, a better solution is to use and semaphore, that is, take the left and right as an atomic operation, the release of the same, can be optimized point, after the current eating, check the left and right is not in a hungry state, need to wake up to eat.

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include < stdbool.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h&
Gt #include <sys/ipc.h> #include <sys/sem.h> #include <sys/wait.h> #ifdef _sem_semun_undefined Union sem
    UN {int val;
    struct Semid_ds *buf;
    unsigned short *array;
struct Seminfo *__buf;
}; #endif #define ERR_EXIT (m) \ Do {\ perror (m); \ EXIT (exit_failure), \} while (0) int wait_1fork
(int no,int semid)
    {//int left = no;
    int right = (no + 1)% 5;
    struct SEMBUF sb = {no,-1,0};
    int ret;
    ret = SEMOP (semid,&sb,1);
    if (Ret < 0) {err_exit ("Semop");
return ret;
    int free_1fork (int no,int semid) {struct Sembuf sb = {no,1,0};
    int ret;
    ret = SEMOP (semid,&sb,1);
    if (Ret < 0) {err_exit ("Semop");
return ret; }

//This indicates that the fork is a critical resource #define DELAY (rand ()% 5 + 1)//equivalent to P operation void Wait_for_2fork (int no,int semid) {//The Philosopher's left knife and fork numbered int le
    FT = no;

    Right knife and fork int right-hand = (no + 1)% 5;
    Knife and fork value is two//note the first parameter is numbered struct SEMBUF buf[2] = {{left,-1,0}, {right,-1,0}};
There are 5 signals in the signal concentration, only the//resource sembuf Operation Semop (semid,buf,2);
    }//equivalent to V operation void Free_2fork (int no,int semid) {int left = no;
    int right = (no + 1)% 5;
    struct SEMBUF buf[2] = {{left,1,0}, {right,1,0}};
Semop (semid,buf,2);
    } void Philosophere (int no,int semid) {Srand (Getpid ()); for (;;) {#if 1//The measure taken here is when both knives and forks are available//philosophers can eat, so that the less neighboring philosophers can//eat the Food printf ("%d is thinking\n", no
        );
        Sleep (DELAY);
        printf ("%d is hungry\n", no);
        Wait_for_2fork (No,semid)//Get a fork to eat printf ("%d is eating\n", no);
        Sleep (DELAY);
Free_2fork (no,semid)/release fork #else//This code may cause deadlock int left = no;        int right = (no + 1)% 5;
        printf ("%d is thinking\n", no);
        Sleep (DELAY);
        printf ("%d is hungry\n", no);
        Wait_1fork (Left,semid);
        Sleep (DELAY);
        Wait_1fork (Right,semid);
        printf ("%d is eating\n", no);
        Sleep (DELAY);
    Free_2fork (No,semid);
    #endif}}: int main (int argc,char *argv[]) {int semid;
    Create semaphore Semid = Semget (ipc_private,5,ipc_creat | 0666);
    if (Semid < 0) {err_exit ("Semid");
    Union Semun Su;
    Su.val = 1;
    int i;
    for (i = 0;i < 5;++i) {//Note the second parameter is also an index semctl (SEMID,I,SETVAL,SU);
    //Create 4 child processes int num = 0;
    pid_t pid;
        for (i = 1;i < 5;++i) {pid = fork ();
        if (PID < 0) {err_exit ("fork");
            } if (0 = = pid) {num = i;
        Break
    }//Here is what the philosopher is going to do Philosophere (NUM,SEMID);
return 0; }

producer Consumer issues
The problem is that access to the buffer is mutually exclusive, so a semaphore mutex is required, and then the producer cannot put in the product, so a full variable is required to display the product, Empty after the consumer can not take, so need a empty to save the number of items can also be placed, each time down the operation of the mutex, release the first release mutex, you can try to write code.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.