[Linux] Inter-process communication - System V semaphore

Table of contents

words written in front

understanding of some concepts

The introduction of semaphores

The concept and use of semaphores


 

words written in front

        System V semaphores are a lower-level IPC mechanism that requires manual manipulation and synchronization when used. In modern operating systems, POSIX semaphores ( sem_*operated through a series of functions) or more advanced synchronization primitives (such as mutexes, condition variables, etc.) are more commonly used to achieve inter-process communication and synchronization. So here I will only talk about the general process of use, but explain it in detail. We will explain in detail later in POSIX semaphores.

understanding of some concepts

        Our last article talked about System V shared memory, we can know:

In order to allow inter-process communication ---> need to allow different processes to see the same resource ---> including all previous communication methods, it is a priority to solve a problem: let different processes see the same resource.

        However, allowing different processes to see the same resource, such as shared memory, will bring some timing problems . For example, the writer only writes half of it and the reader just reads it away. That is, the lack of access control will cause data inconsistency . .

        The internal OS of the pipeline has already handled these, so there is no need to care about these timing issues.

        here we

        1. A common resource seen by multiple processes (execution flow) is called a critical resource

        2. Call your own process and the code that accesses critical resources a critical section .

For example the example from the previous chapter:

         All the code only has these two lines to access the critical resource shmaddr, so it is called a critical section.


When using shared memory, multiple execution streams interfere with each other while running. The main reason is that we accessed the same resource (critical resource) without protection . In a non-critical section, multiple execution streams do not affect each other.

        3. In order to better protect the critical area, only one process can enter and access the critical area at any time in the multi-execution flow , which is called mutual exclusion . This mutual exclusion will be explained in detail later in multithreading.


The introduction of semaphores

        Let me give an example first: When we go to the movies, we must have a seat (a resource in the screening hall). Does this seat belong to you only if you sit on it? Obviously not, I have to buy a ticket first, as long as I buy a ticket, I have this seat, no matter whether I am there or not, that seat belongs to me.

        So the essence of buying tickets: the |reservation| mechanism for seats .         

        Correspondingly, each process wants to enter a critical resource and access a part of the critical resource. The process cannot be allowed to use the critical resource directly (the user cannot go directly to the movie theater to grab a seat), but to apply for a semaphore first (first come to buy a ticket).

        The essence of the semaphore is a counter , similar to int count = n (a less accurate example, for now, understand it this way).

        So apply for the semaphore:

        1. The essence of applying for a semaphore is: let the semaphore counter --

        2. As long as the application for the semaphore is successful, the resources you want must be reserved inside the critical resource --- the application for the semaphore is actually a reservation mechanism for the critical resource.

       3. Similarly, the use of critical resources needs to release the semaphore, which is essentially semaphore++.

        Assuming that there are 10 small resources in a critical resource, and there are 11 processes at this time, then the first 10 processes access the critical resource and apply for a semaphore successfully. The last process can only block because the resources in the critical resource are being used. Wait for the resources of the process inside to be used up.


        The above has been talking about semaphores, so what exactly is a semaphore ?

        It is mentioned above that the semaphore is a counter , so what is this counter?

        First of all, the counter must not be a local variable , so the counter cannot be associated with each process, because each process has its own counter, which is absurd.

        If it is a global variable, when the parent and child processes apply for the semaphore, copy-on-write will occur, causing the parent and child processes to each have a copy of the variable, which is not good.

        Then assume that multiple processes can see the same n, (that is, n is in the shared memory), and then everyone can apply for the semaphore at this time?

The answer is also no .

        First of all, we need to know that the calculation is performed in the CPU, and the data n is stored in the memory.

When the CPU executes an instruction, it needs to do the following three steps:

        1. Load the data in the memory to the CPU register

        2.n--(analyze && execute instructions)

        3. Write the modified n of the cpu back to the memory.

        This seems to be fine, but the execution flow may be switched at any time during execution.

        When it is switched, it will take away its own context data (including n), and then when it is switched back, it will write its own context data into the cpu register and continue to execute.

So there is a problem:

        Suppose there are 10 processes, respectively 1, 2, 3, 4..., 9, 10, and there are only 5 critical resources, so the semaphore n is also 5.

        Assume that 1 applies for a semaphore first, but is unlucky to execute the first step and is cut off. Then 2, 3, 4, 5, and 6 all apply for a semaphore normally. At this time, the semaphore is already 0, and the following 7 You can no longer apply for the process up to 10.

        But at this time, No. 1 continues to execute again. Since n is 5 when it comes in for the first time, continue to execute steps 2 and 3, n-- is 4, and then write it back to the memory. At this time, n changes from 0 to 4 , Isn’t this bad? Obviously there are no resources, but the semaphore becomes 4, and the subsequent process can continue to apply, so it must be wrong.       

        So n--because of timing problems, n has an intermediate state, which may cause data inconsistency, but if n has only one line of assembly, then the operation is atomic !

So 4. Atomicity: Either do not do it, or do it, there is no intermediate state, it is called atomicity .


The concept and use of semaphores

concept:

A System V semaphore is an interprocess communication (IPC) mechanism provided in the operating system to implement synchronization and mutual exclusion between processes. It controls access to resources by operating on counters.

System V semaphores are identified by an integer identifier (semaphore identifier), and each identifier corresponds to a semaphore set (semaphore set). A semaphore set can contain multiple individual semaphores, each with a non-negative integer value.

use:

System V semaphores provide the following three basic operations:

  1. Create Semaphore Set: semget()Create a new semaphore set using a system call. This call returns a semaphore identifier for subsequent semaphore operations.

  2. Controlling semaphore collections: Use semctl()system calls to control semaphore collections. Through this call, you can set the initial value of the semaphore, obtain or change the value of the semaphore, delete the semaphore set, and so on.

  3. Manipulating semaphores: Use semop()system calls to manipulate semaphores. The call accepts a semaphore identifier and a set of operations that can be used to acquire or release the semaphore and perform other control operations.

semop()The operations accepted by the system call include:

  • P (wait) operation: By decrementing the value of the semaphore by one (if the semaphore value is greater than zero), or making the calling process enter a wait state (if the semaphore value is zero).
  • V (release) operation: by adding one to the value of the semaphore, and waking up other processes waiting for the semaphore.
  • Through proper combination and operation, mutually exclusive access to resources and concurrency control can be realized. Multiple processes can coordinate their actions through the operation of the semaphore to ensure data consistency and correctness.

When introducing System V semaphore-related functions, commonly used functions include semget(), , semctl()and semop(). The following will introduce their parameters and usage:

  1. semget()function:

    int semget(key_t key, int nsems, int semflg);
    
    • parameter:
      • key: Unique key value, used to identify the set of semaphores to be created or acquired.
      • nsems: Specifies the number of semaphores in the semaphore set.
      • semflg: Flag parameter, used to specify the creation method and access rights of the semaphore.
    • usage:
      • By specifying a key value and other parameters, the calling semget()function can create a new semaphore set, or obtain an existing semaphore set.
      • The return value is a semaphore identifier, which is used for subsequent control and operation of the semaphore set.
  2. semctl()function:

    int semctl(int semid, int semnum, int cmd, ...);
    
    • parameter:
      • semid: The semaphore identifier, used to specify the set of semaphores to be operated.
      • semnum: Specify the index of the specific semaphore in the collection, which is used to identify the semaphore to be operated.
      • cmd: The control command to execute, used to specify a specific operation.
      • arg: Parameters that need to be provided according to different commands.
    • usage:
      • semctl()Functions are used to control and manage semaphore collections.
      • Different operations can be achieved by specifying different control commands ( cmd), such as setting the initial value of the semaphore, obtaining or changing the value of the semaphore, and deleting the semaphore set.
      • The exact parameters (eg arg) vary from command to command.
  3. semop()function:

    int semop(int semid, struct sembuf *sops, unsigned nsops);
    
    • parameter:
      • semid: The semaphore identifier, used to specify the set of semaphores to be operated.
      • sops: sembufA pointer to a structure array, which contains a set of operations.
      • nsops: Specifies the number of operations.
    • usage:
      • semop()Functions are used to operate on semaphores.
      • By combining different operations, operations such as acquisition and release of semaphores can be realized.
      • sopsThe parameter is a sembufpointer to a structure array, and sembufthe structure defines the specific information of each operation, including the number of the semaphore, the operation type (P operation or V operation), and the operation flag.
      • nsopsThe parameter specifies the number of operations to perform.

in. The sembuf structure is roughly as follows:

 

sembufA structure is a structure used to specify operations in a System V semaphore, and it contains the following fields:

  1. unsigned short sem_num: Specifies the index of the semaphore to be operated in the collection, counting from 0.
  2. short sem_op: Specifies the action to perform.
    • If sem_opthe value is greater than 0, it means that the V (release) operation is performed, that is, the value of the semaphore is increased.
    • If sem_opthe value is less than 0, it means to perform P (wait) operation, that is, reduce the value of the semaphore.
    • If sem_opthe value of the semaphore is equal to 0, it means that the Z (zero) operation is performed, and if the value of the semaphore is 0, it waits. This operation is typically used in synchronous operations to wait for a certain condition to occur.
  3. short sem_flg: Flags used to specify an action.
    • IPC_NOWAIT: If the operation cannot be performed (for example, the value of the semaphore is 0 and sem_opnegative), return immediately without waiting.
    • SEM_UNDO: When the process terminates unexpectedly, the system will automatically cancel the operation of the process on the semaphore to avoid deadlock.

Guess you like

Origin blog.csdn.net/weixin_47257473/article/details/132136874