Sincronización de semáforos para hilos de Linux

  
        

La diferencia entre semáforos y mutex: Mutexes permite que solo un hilo ingrese a la sección crítica, mientras que los semáforos permiten que múltiples hilos ingresen a la sección crítica simultáneamente.

Sin más explicación, para usar la sincronización de semáforos, debe incluir el archivo de encabezado semaphore.h.

Funciones utilizadas principalmente:

  • int sem_init (sem_t * sem, int pshared, unsigned int value);, donde sem es el semáforo que se va a inicializar, y pshared es la señal Si la cantidad se comparte entre procesos o se comparte entre hilos, el valor es el valor inicial del semáforo.
  • int sem_destroy (sem_t * sem);, donde sem es el semáforo que se destruirá. Solo los semáforos inicializados con sem_init se pueden destruir con sem_destroy.
  • int sem_wait (sem_t * sem); espere el semáforo, si el valor del semáforo es mayor que 0, reduzca el valor del semáforo en 1 y regrese inmediatamente. Si el valor del semáforo es 0, el hilo se bloquea. Equivalente a la operación P. Devuelve con éxito 0 y devuelve error -1.
  • int sem_post (sem_t * sem); Libera el semáforo e incrementa el semáforo en 1. Equivalente a la operación V.

    El siguiente código muestra cómo simular un sistema de servicio de ventana con sincronización de semáforo.

     /* @purpose: sincronización de subprocesos múltiples basada en semáforos, operaciones P, V en el principio del sistema operativo * @author: [email protected] * @create: 2015-03-20 Fri * * /#include < pthread.h &> #include < semaphore.h > #include < unistd.h > #include < stdio.h > #include < stdlib.h > Sólo puede servir a dos clientes. * Cuando vengan varios clientes, cada cliente esperará si encuentra que la ventana de servicio está llena. * Si hay una ventana de servicio disponible, aceptarán el servicio. * //* Defina los semáforos como variables globales para facilitar el intercambio de * /sem_t sem por múltiples subprocesos; /* Rutinas que se ejecutarán por subproceso * /void * get_service (void * thread_id) {/* Nota: Guardar thread_id inmediatamente El valor, ya que thread_id es una referencia a la variable de bucle i en el subproceso principal, se puede modificar inmediatamente * /int customer_id = * ((int *) thread_id); if (sem_wait (&sem) == 0) {usleep ( 100); /* service time: 100ms * /printf (" customer% d recibe service ... \\ n ", customer_id); sem_post (&sem);}} # define CUSTOMER_NUM 10int main (int argc, char * Argv []) {/* Inicializa el semáforo con un valor inicial de 2, lo que indica que dos clientes pueden recibir el servicio al mismo tiempo * //* @prototype: int sem_init (sem_t * sem, int pshared, unsigned int value); * //* pshared: si pshared == 0, el semáforo se comparte entre subprocesos de un proceso * de lo contrario, el semáforo se comparte entre procesos. * /sem_init (&sem, 0, 2); /* define una identificación de subproceso para cada cliente , pthread_t es en realidad sin firmar Long int * /pthread_t clientes [CUSTOMER_NUM]; int i, ret; /* Generar un subproceso para cada cliente * /for (i = 0; i < CUSTOMER_NUM; i ++) {int customer_id = i; ret = pthread_create (&clients [i], NULL, get_service, &customer_id); if (ret! = 0) {perror (" pthread_create "); exit (1);} else {printf (" Cliente% d llegado. \\ n ", i);} usleep (10);} /* Espere a que terminen los hilos de todos los clientes * //* Nota: Este lugar ya no puede usar i como una variable de bucle, ya que se puede acceder al valor de i en el hilo * /int j; For (j = 0; j < CUSTOMER_NUM; j ++) {pthread_join (clientes [j], NULL);} /* Solo un semáforo que haya sido inicializado por sem_init (3) * debe destruirse utilizando sem_destroy (). * /Sem_destroy (&sem); return 0;} 

    Compile: gcc main.c -lpthread.

    Resultados de la ejecución (tenga en cuenta que cada ejecución es diferente):

     Llegó el cliente 0. El cliente 1 llegó. El cliente 0 recibió el servicio ... El cliente 2 llegó. El cliente 1 recibió el servicio ... . El cliente 3 llegó. El cliente 2 recibió el servicio ... El cliente 4 llegó. El cliente 3 recibió el servicio ... El cliente 5 llegó. El cliente 4 recibió el servicio ... El cliente 6 llegó. El cliente 5 recibió el servicio ... El cliente 7 llegó. El cliente 6 recibir servicio ... Cliente 8 arribó. Cliente 7 recibir servicio ... Cliente 9 arribó. Cliente 8 recibir servicio ... cliente 9 recibir servicio ...
    						
  • Copyright © Conocimiento de Windows All Rights Reserved