interprocess communication Quad (semaphore)

Source: Internet
Author: User
Tags mutex rand semaphore

1. What is semaphore?

To prevent a series of problems that arise from the simultaneous access of multiple programs to a shared resource, we need a method that can be authorized by generating and using tokens, and at any one time there can be only one critical region that executes thread access code. A critical region is a code that performs data updates that needs to be executed exclusively.  And semaphores can provide such an access mechanism, so that a critical section at the same time only one thread is accessing it, that is, the semaphore is used to attune process access to shared resources. A semaphore is a special variable whose access is atomic, and only allows it to wait (that is, p (signal variable)) and send (that is, V (signal variable)) information operation. The simplest semaphore is a variable of only 0 and 1, which is also the most common form of semaphore, called the binary semaphore. A semaphore that can take multiple positive integers is called a generic semaphore. The main discussion here is the binary signal volume. 2. How the semaphore works because the semaphore can only perform two operation wait and send signals, namely P (SV) and V (SV), their behavior is this: P (SV): If the value of SV is greater than 0, give it minus 1, if its value is zero, suspend the execution of the process V (SV) : If another process is suspended because it waits for the SV, let it run again, and if no process is suspended because it waits for the SV, add 1 to it. For example, two processes share the semaphore SV, and once one of the processes performs a P (SV) operation, it will get the semaphore and can enter the critical section, reducing the SV by 1. The second process is prevented from entering the critical section because when it attempts to execute P (SV), the SV is 0, it is suspended to wait for the first process to leave the critical area and performs a V (SV) Release semaphore, and the second process can resume execution. 3. Linux semaphore mechanism Linux provides a set of well-designed semaphore interfaces to operate on signals that are not just for binary semaphores, but are described below, but note that these functions are used to manipulate the set of semaphore values. They are declared in the header file sys/sem.h. 3.1 Semget function Its function is to create a new semaphore or to obtain an existing semaphore, the prototype is:int Semget (key_t key, int num_sems, int sem_flags); The first parameter, key, is an integer value (unique not 0), and an unrelated process can access a semaphore, which represents a resource that the program may want to use, and the program accesses all semaphores indirectly, by calling the Semget function and providing a key. The system generates a corresponding signal identifier (the return value of the Semget function), and only the Semget function uses the semaphore key directly, and all other semaphore functions use the semaphore identifier returned by the Semget function. If multiple programs use the same key value, key will be responsible for coordinating the work. The second parameter, Num_sems, specifies the number of semaphores required, and its value is almost always 1. The third parameter, Sem_flags, is a set of flags that, when you want to create a new semaphore when the semaphore does not exist, you can do a bitwise OR operation with the value ipc_creat. When the IPC_CREAT flag is set, the given key is not an error if it is a key that already has a semaphore. and Ipc_creat | IPC_EXCL can create a new, unique semaphore that returns an error if the semaphore already exists. The Semget function successfully returns a corresponding signal identifier (not 0), and the failure returns-1. 3.2 Semop function It is to change the value of the semaphore, the prototype is:int semop (int sem_id, struct sembuf *sem_opa, size_t num_sem_ops); SEM_ID is the semaphore identifier returned by Semget, and the SEMBUF structure is defined as follows:struct sembuf{

Short sem_num; //Unless a set of semaphores is used, it is 0

        Short sem_op; //Semaphore the data that needs to be changed in a single operation, usually two numbers, one is-1, that is, p (wait) operation,  one is +1, which is the V (Send signal) operation.

        Short SEM_FLG; //usually Sem_undo, which enables the operating system to trace signals, and when the process terminates without releasing the semaphore, the operating system releases the semaphore


3.3 Semctl function This function is used to directly control the semaphore information, its prototype is:int semctl (int sem_id, int sem_num, int command, ...); If there is a fourth argument, it is usually a union semum structure, defined as follows:Union semun{

int Val;

        struct Semid_ds *buf;

unsigned short *arry;


The first two arguments are the same as in the previous one, and the command is usually one of the following two values: used to initialize the semaphore to a known value, Setval. P This value is set by the Val member in the Union Semun, which is set before the semaphore is used for the first time. Ipc_rmid: Used to delete a semaphore identifier that has not been used for further use. 4. Process using semaphore communication below is an example of how the semaphore is used to communicate between processes, this example is two identical programs simultaneously output data to the screen, we can see how to use semaphores to coordinate the work of two processes so that only one process at a time can output data to the screen. Note that if the program is first called (in order to differentiate, the first time the program is called with a character to output to the screen as a parameter), you need to call the Set_semvalue function to initialize the signal and set the message character to the first character of the argument passed to the program, The first process that starts is also responsible for the deletion of semaphores. If you do not delete the semaphore, it will continue to exist in the system, even if the program has exited, it may cause problems the next time you run this program, and the semaphore is a limited resource. Call Semget in the main function to create a semaphore that returns a semaphore identifier stored in the global variable sem_id, which is then used by subsequent functions to access the semaphore. The source file is semaphore.c and the code is as follows:
  1. #include <unistd.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <sys/sem.h>
  9. Union Semun
  10. {
  11. int val;
  12. struct Semid_ds *buf;
  13. unsigned short *arry;
  14. };
  15. static int sem_id = 0;
  16. static int set_semvalue ();
  17. static void Del_semvalue ();
  18. static int semaphore_p ();
  19. static int semaphore_v ();
  20. int main (int argc, char *argv[])
  21. {
  22. char message = ' X ';
  23. int i = 0;
  24. //Create semaphores
  25. sem_id = Semget ((key_t) 1234, 1, 0666 | Ipc_creat);
  26. if (argc > 1)
  27. {
  28. //program is called for the first time, initializing the semaphore
  29. if (!set_semvalue ())
  30. {
  31. fprintf (stderr, "Failed to initialize semaphore\n");
  32. Exit (Exit_failure);
  33. }
  34. //Set the information to be output to the screen, i.e. the first character of its argument
  35. message = Argv[1][0];
  36. Sleep (2);
  37. }
  38. For (i = 0; i <; ++i)
  39. {
  40. //Enter the critical section
  41. if (!semaphore_p ())
  42. Exit (Exit_failure);
  43. //Output data to the screen
  44. printf ("%c", message);
  45. //clean buffer, then hibernate random time
  46. Fflush (stdout);
  47. Sleep (rand ()% 3);
  48. //exit the critical section before outputting data to the screen again
  49. printf ("%c", message);
  50. Fflush (stdout);
  51. //Leave critical section, resume cycle after a random time of sleep
  52. if (!semaphore_v ())
  53. Exit (Exit_failure);
  54. Sleep (rand ()% 2);
  55. }
  56. Sleep (10);
  57. printf ("\n%d-finished\n", Getpid ());
  58. if (argc > 1)
  59. {
  60. //If the program is called for the first time, remove the semaphore before exiting
  61. Sleep (3);
  62. Del_semvalue ();
  63. }
  64. Exit (exit_success);
  65. }
  66. static int Set_semvalue ()
  67. {
  68. //Used to initialize semaphores, this must be done before using semaphores
  69. Union Semun Sem_union;
  70. Sem_union.val = 1;
  71. if (semctl (sem_id, 0, setval, sem_union) = =-1)
  72. return 0;
  73. return 1;
  74. }
  75. static void Del_semvalue ()
  76. {
  77. //delete semaphore
  78. Union Semun Sem_union;
  79. if (semctl (sem_id, 0, ipc_rmid, sem_union) = =-1)
  80. fprintf (stderr, "Failed to delete semaphore\n");
  81. }
  82. static int semaphore_p ()
  83. {
  84. //To reduce the semaphore by 1 operation, that is, wait P (SV)
  85. struct SEMBUF sem_b;
  86. Sem_b.sem_num = 0;
  87. Sem_b.sem_op =-1; //p ()
  88. SEM_B.SEM_FLG = Sem_undo;
  89. if (Semop (sem_id, &sem_b, 1) = =-1)
  90. {
  91. fprintf (stderr, "semaphore_p failed\n");
  92. return 0;
  93. }
  94. return 1;
  95. }
  96. static int Semaphore_v ()
  97. {
  98. //This is a release operation that makes the signal available, i.e. Send signal V (SV)
  99. struct SEMBUF sem_b;
  100. Sem_b.sem_num = 0;
  101. Sem_b.sem_op = 1; //v ()
  102. SEM_B.SEM_FLG = Sem_undo;
  103. if (Semop (sem_id, &sem_b, 1) = =-1)
  104. {
  105. fprintf (stderr, "Semaphore_v failed\n");
  106. return 0;
  107. }
  108. return 1;
  109. }
The results of the operation are as follows:

[[email protected] program1] $ls
[[email protected] program1] $GCC semaphore.c-o semaphore
[email protected] Program1]$./semaphore 0 &/semaphore
[1] 3505
[Email protected] program1]$

[1]+ done./semaphore 0
[Email protected] program1]$

Note: The critical section of this program is the code in the middle of the semaphore_p and SEMAPHORE_V functions for the main function for loop. Example analysis: Run two instances of a program at the same time, note that the first run, with a character as a parameter, such as the character ' O ' in this example, is used to differentiate whether it is the first call, and this character is output to the screen. Because each program prints a character before it enters the critical section and before it leaves the critical section, each character should appear in pairs, as you see in the output. In the main function loop we can see that every time the process wants to access stdout (standard output), that is, to output characters, each time to check whether the semaphore is available (that is, stdout is not being used by another process). Therefore, when a process a calls the function Semaphore_p enters the critical section, after the output character, call sleep, another process B may want to access stdout, but the semaphore p request operation fails, can only suspend its own execution, when process a calls the function semaphore_ V leaves the critical section, and process B is immediately resumed execution.  Then process A and process B have been circulating 10 times. 5. The sum of the semaphore is a special variable whose access is atomic and allows only waiting (that is, p (signal variable)) and sending (i.e. V (signal variable)) information operations.  We usually use signals to solve the problem of multiple process access to the same resource, so that at any one time there can be only one critical region to execute thread access code, or it can be said to coordinate access to the same resource between processes, that is, for the synchronization process. The intent of the semaphore is inter-process synchronization, and the intent of the mutex and condition variables is synchronization between threads. But semaphores can also be used between threads, and mutex and condition variables can also be used for inter-process text:

interprocess communication Quad (semaphore)

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: 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.