Semaphore synchronization for Linux threads

  
        

The difference between semaphores and mutex: Mutexes allow only one thread to enter the critical section, while semaphores allow multiple threads to enter the critical section simultaneously.

No more explanation, to use semaphore synchronization, you need to include the header file semaphore.h.

Mainly used functions:

  • int sem_init(sem_t *sem, int pshared, unsigned int value);, where sem is the semaphore to be initialized, and pshared is the signal Whether the amount is shared between processes or shared between threads, value is the initial value of the semaphore.
  • int sem_destroy(sem_t *sem);, where sem is the semaphore to be destroyed. Only semaphores initialized with sem_init can be destroyed with sem_destroy.
  • int sem_wait(sem_t *sem); Wait for the semaphore, if the value of the semaphore is greater than 0, decrement the value of the semaphore by 1 and return immediately. If the value of the semaphore is 0, the thread is blocked. Equivalent to P operation. Successfully returns 0, and failure returns -1.
  • int sem_post(sem_t *sem); Release the semaphore and increment the semaphore by 1. Equivalent to V operation.

    The following code demonstrates how to simulate a window service system with semaphore synchronization.

    /* @purpose: Multi-thread synchronization based on semaphores, P, V operations in the operating system principle * @author: [email protected] * @create: 2015-03-20 Fri * */#include <pthread.h>#include <semaphore.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>/* @Scene: An industry business hall at the same time Can only serve two customers. * When there are multiple customers coming, each customer will wait if they find that the service window is full. * If there is a service window available, they will accept the service. *//* Define semaphores as global variables to facilitate sharing of */sem_t sem by multiple threads; /* Routines to be run per thread */void * get_service(void *thread_id){ /* Note: Save thread_id immediately The value, because thread_id is a reference to the loop variable i in the main thread, it may be modified immediately */int customer_id = *((int *)thread_id); if(sem_wait(&sem) == 0) { usleep( 100); /* service time: 100ms */printf("customer %d receive service ...\ ", customer_id); sem_post(&sem); }}#define CUSTOMER_NUM 10int main(int argc, char * Argv[]){ /* Initializes the semaphore with an initial value of 2, indicating that two customers can receive the service at the same time *//* @prototype: int sem_init(sem_t *sem, int pshared, unsigned int value); *//* pshared: if pshared == 0, the semaphore is shared among threads of a process * otherwise the semaphore is shared between processes. */sem_init(&sem, 0, 2); /* defines a thread id for each customer , pthread_t is actually unsigned Long int */pthread_t customers[CUSTOMER_NUM]; int i, ret; /* Generate a thread for each customer */for(i = 0; i < CUSTOMER_NUM; i++){ int customer_id = i; ret = pthread_create(& ;customers[i], NULL, get_service, &customer_id); if(ret != 0){ perror("pthread_create"); exit(1); } else { printf("Customer %d arrived.\ " ;, i); } usleep(10); } /* Wait for all customers' threads to end *//* Note: This place can no longer use i as a loop variable, because the value of i may be accessed in the thread */int j; For(j = 0; j < CUSTOMER_NUM; j++) { pthread_join(customers[j], NULL); } /* Only a semaphore that has been initialized by sem_init(3) * should be destroyed using sem_destroy().*/Sem_destroy(&sem); return 0;}

    Compile: gcc main.c -lpthread.

    Run results (note that each run is different):

    Customer 0 arrived.Customer 1 arrived.customer 0 receive service ...Customer 2 arrived.customer 1 receive service .. .Customer 3 arrived.customer 2 receive service ...Customer 4 arrived.customer 3 receive service ...Customer 5 arrived.customer 4 receive service ...Customer 6 arrived.customer 5 receive service ...Customer 7 arrived.customer 6 receive service ...Customer 8 arrived.customer 7 receive service ...Customer 9 arrived.customer 8 receive service ...customer 9 receive service ...
  • Copyright © Windows knowledge All Rights Reserved