Detailed explanation of Linux semaphore

1. What is a semaphore

The essence of the semaphore is a data operation lock, which is responsible for mutual exclusion, synchronization and other functions in the data operation process.

A semaphore is similar to a mutex and is essentially a counter (global variable). The difference is that there are only two values ​​of the mutex (lock "lock" and unlock "unlock"), and the value of the semaphore can be set according to the needs of the actual scene (the value range is ≥0). When a process requests the resource it manages, the process must first read the value of the semaphore. If it is greater than 0, the resource can be requested. If it is equal to 0, the resource is unavailable. At this time, the process will enter the sleep state until the resource is available. When a process no longer uses resources, the semaphore +1 (the corresponding operation is called V operation), on the contrary, when a process uses resources, the semaphore -1 (the corresponding operation is P operation). Value operations on semaphores are atomic operations .

2. Classification of semaphores

According to different initial values, semaphores can be subdivided into two types, namely binary semaphores and counting semaphores:

  • Binary semaphore: refers to a semaphore with an initial value of 1. This type of semaphore has only two values ​​​​of 1 and 0. It is usually used to replace mutex locks to achieve thread synchronization;

  • Counting semaphore: refers to the semaphore with an initial value greater than 1. When there are multiple threads in the process, but the number of threads allowed to access a certain public resource at the same time is limited (the situation of "more wolves and less meat" appears), then you can Use a counting semaphore to limit the number of threads that can simultaneously access a resource.

According to the different usage scenarios, it can be divided into two categories: unnamed semaphore and named semaphore

  • Unnamed semaphores can only be used in the case of shared memory, such as mutual exclusion and synchronization between threads in a process , so unnamed semaphores are also called memory-based semaphores;

  • Named semaphores are often used in situations where memory is not shared, such as interprocess communication .

3. API of semaphore

3.1 Unnamed semaphore

The functions of the semaphore all start with sem_, and there are four basic signal functions used in the thread. They are all declared in the header file semaphore.h, which defines the sem_t type for semaphore operations:

【sem_init】:

This function is used to create a semaphore, the prototype is as follows:

intsem_init(sem_t *sem,int pshared,unsignedint value);

This function initializes the signal object pointed to by sem, sets its shared options, and gives it an initial integer value. pshared controls the type of semaphore. If its value is 0, it means that the semaphore is a local semaphore of the current process . Otherwise, the semaphore can be shared among multiple processes, and the value is the initial value of sem.

The function call returns 0 on success and -1 on failure.

【sem_destroy】:

This function is used to clean up the exhausted semaphore, and its prototype is as follows:

intsem_destroy(sem_t *sem);

Returns 0 on success and -1 on failure.

[sem_wait function]:

This function is used to atomically decrement the value of the semaphore by 1. An atomic operation is that if two threads attempt to add or subtract 1 to a semaphore at the same time, they will not interfere with each other. Its prototype is as follows:

intsem_wait(sem_t *sem);
intsem_trywait(sem_t *sem);
intsem_timedwait(sem_t *sem, conststructtimespec*abs_timeout);

The object pointed to by sem is the semaphore initialized by the sem_init call. The call returns 0 on success and -1 on failure.

sem_trywait() is a non-blocking version of sem_wait(). When the condition is not met (the semaphore is 0), the function directly returns the EAGAIN error without blocking the wait.

The function of sem_timedwait() is similar to sem_wait(), it just waits within the specified abs_timeout time, and returns ETIMEDOUT error directly if the time exceeds. abs_timeout is the UTC timestamp

https://www.cnblogs.com/coding-my-life/p/4085336.html

[sem_post function]:

This function is used to increase the value of the semaphore by 1 in an atomic operation, and its prototype is as follows:

intsem_post(sem_t *sem);

Like sem_wait, the object pointed to by sem is a semaphore initialized by a sem_init call. Returns 0 when the call is successful, and returns -1 if it fails.

[sem_getvalue function]:

This function returns the value of the current semaphore, which is returned through the restrict output parameter. If the current semaphore is already locked (that is, the synchronization object is unavailable), then the return value is 0, or a negative number, and its absolute value is the number of threads waiting for the semaphore to be unlocked.

intsem_getvalue(sem_t *restrict,int*restrict);

3.2 Well-known semaphores

It is called a named semaphore because it has a name, a user ID, a group ID, and permissions. These are the interfaces provided to those processes that do not share memory to use named semaphores. The name of a named semaphore is a string that follows the rules for pathname construction.

[sem_open function]:

This function is used to create or open a named semaphore, and its prototype is as follows:

sem_t *sem_open(constchar*name,int oflag);
sem_t *sem_open(constchar*name,int oflag,
                mode_t mode,unsignedint value);

The parameter name is a string identifying the semaphore. The parameter oflag is used to determine whether to create a semaphore or connect an existing semaphore.

The parameter of oflag can be 0, O_CREAT or O_EXCL: if it is 0, it means to open an existing semaphore; if it is O_CREAT, it means to create a semaphore if it does not exist, and if it exists, it will be opened and returned. At this time, mode Both value and value need to be specified; if it is O_CREAT|O_EXCL, it means that if the semaphore exists, an error will be returned.

The mode parameter is used to specify the permission bit of the semaphore when creating the semaphore, which is the same as the open function, including: S_IRUSR, S_IWUSR, S_IRGRP, S_IWGRP, S_IROTH, S_IWOTH.

value indicates the initial value of the semaphore when the semaphore is created.

[sem_close function]:

This function is used to close the named semaphore:

intsem_close(sem_t *);

A single program can close a named semaphore with the sem_close function, but doing so does not remove the semaphore from the system because named semaphores are persistent beyond a single program execution. Named semaphores opened by the process are also closed when the process calls _exit, exit, exec, or returns from main.

[sem_unlink function]:

The sem_unlink function is used to remove the semaphore from the system after all processes have closed the named semaphore:

intsem_unlink(constchar*name);

[Semaphore operation function]:

Like the unnamed semaphore, the functions that operate on the semaphore are as follows:

intsem_wait(sem_t *sem);
intsem_trywait(sem_t *sem);
intsem_timedwait(sem_t *sem,conststructtimespec*abs_timeout);
intsem_post(sem_t *sem);
intsem_getvalue(sem_t *restrict,int*restrict);

ref:

http://c.biancheng.net/view/8632.html

https://www.jianshu.com/p/6e72ff770244

Guess you like

Origin blog.csdn.net/wwwlyj123321/article/details/129375900