The so-called semaphore is actually a number. The kernel assigns a certain meaning to this number, making it different in meaning when it equals a different value. This allows you to use it to indicate whether a resource is being used. The classification of the signal is actually quite many, mainly two values and counters. Two values are discussed here
Now there is a file that has two processes to access it at the same time. Process a writes "Math class is Cancel" to the inside, and process B writes "English test" to it. Normally, these two messages are written to the file in full. However, if process a writes to "math class" and pauses, then the B process begins writing "English test", and process a continues to write the remaining "is Cancel", and the final result of the file is "math class 中文版 test is Cancel". The result was obviously wrong. The reason for the error is actually very simple, two processes at the same time common one resource but there is no mechanism to control the sequencing of access. Because Linux is a multitasking system, it is common for resources to be accessed concurrently by multiple tasks. We need a mechanism to control how resources can be accessed in an orderly manner. The semaphore is an implementation.
The implementation mechanism of the mutual exclusion of semaphores is briefly described as follows:
Let two processes test the semaphore sig before actually writing the data. When process a writes to a file, it tests the semaphore sig, if the semaphore sig equals 1, indicating that the file is not being reused by another process, then it will subtract 1 of the semaphore so that it equals 0, and then write the data directly to the file. However, when process B tests the semaphore sig to find that it equals 0, indicating that a process is using it, the kernel lets process B hang, and it can continue the write operation when the semaphore value is set to 1. 、
The mechanism of describing the semaphore can be used to discuss the implementation of the Linux kernel for semaphores.
The fact that the Linux kernel has a very simple interface to the semaphore. Just three functions:
int Semget (key_t key, int num_sems, int sem_flags);
int semop (int semid, struct sembuf *sops, size_t ops_num);
int semctl (int semid, int semnum, int command, ...);
Semget function
The function is to create/open a set of semaphores, so-called sets are actually equivalent to arrays. A process may be associated with multiple resources, and multiple semaphores can be used to control access to those resources. It is reasonable to see the concept of the set of semaphores provided by the Linux kernel. Its parameters and return values are discussed below:
The return value is simple, an integer----The semaphore identifier, which is allocated by the kernel for each set of semaphore that is opened, and access to a collection of semaphores depends on it (the file descriptor in the analogy file programming). Key parameter: value. The kernel maintains different key values for all semaphore sets, which are present regardless of whether the semaphore set is open. The key value is actually the equivalent of the file name, but the key value is an integer, it can be freely specified, but the free designation is easy to make different semaphores have the same key value. So the kernel provides a function to assign the key value: key_t ftok (const char *pathname, int proj_num); the function synthesizes the key value in a simple description:
A key value key is combined and returned to the caller based on the name pathname the number represented in the kernel and the proj_num. Num_sems parameter: Indicates the number of semaphores in this semaphore set. Sem_flags parameter: Open flag, can take value ipc_creat. When this parameter is present in a function call, and the set of semaphores specified by the key value does not exist, the function creates a semaphore set represented by key.
Semop function
The SEMOP function is used to set the semaphore. In fact, the operation of the semaphore set is very simple, it is simply to add one or minus one, to express the release or to obtain the semaphore. The return value has no meaning except that it represents the success or failure of the operation. Semid parameter: An identifier for an open semaphore collection, returned from Semget. Ops_num parameter: Indicates how many semaphores the operation function operates because the semaphore set may have multiple semaphores. The structure defined for OPS execution is as follows:
struct SEMBUF
{
Unsigned short sem_num;//shows which of these semaphores is in the semaphore set.
Short Sem_op; Indicates that the operation type integer indicates +1 and the negative number indicates-1. Actually getting the semaphore and releasing the semaphore is the difference here.
Short SEM_FLG;
}
Semctl function
The SEMCTL function is a variety of operations performed on semaphores. Semid parameter: An identifier that indicates the set of semaphores to manipulate. Semnum parameter: Indicates the number of semaphores to be manipulated. Command parameter: Indicates the order to execute. When we want to assign an initial value to the semaphore, we can make command = = Setval, and then give the values to be assigned in the omitted arguments.
Function description is done, here is a simple example to test the semaphore mutex programming:
Process A:
#include <sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<sys/ipc.h>#include<sys/sem.h>intMain () {intFD =0; key_t key; intSemid; structSembuf SOPs; //Create and open semaphoresKey = Ftok (" /Home",1); Semid= Semget (Key,1, ipc_creat); Semctl (Semid,0, Setval,1); /*0. Open the announcement bar*/FD= Open ("./board.txt", o_rdwr|o_append); //get the SemaphoreSops.sem_num =0; Sops.sem_op= -1; Semop (Semid,&sops,1); /*1. Write "Math class"*/Write (FD,"Math class", One); /*2. Pause*/Sleep (Ten); /*3. Write "Cancel"*/Write (FD,"Is cancel",Ten); //release SemaphoreSops.sem_num =0; Sops.sem_op=1; Semop (Semid,&sops,1); /*4. Close the publicity bar*/Close (FD); return 0;}
View Code
Process B:
#include <sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<sys/ipc.h>#include<sys/sem.h>intMain () {intFD =0; key_t key; intSemid; structSembuf SOPs; /*0. Open the announcement bar*/FD= Open ("./board.txt", o_rdwr|o_append); //Turn on SemaphoreKey = Ftok (" /Home",1); Semid= Semget (Key,1, ipc_creat); //get the SemaphoreSops.sem_num =0; Sops.sem_op= -1; Semop (Semid,&sops,1); /*1. Write "English class"*/Write (FD,"enclish Exam", -); //release SemaphoreSops.sem_num =0; Sops.sem_op=1; Semop (Semid,&sops,1); /*2. Close the publicity bar*/Close (FD); return 0;}
View Code
Linux Semaphore Mutex programming