Uso de semáforos para controlar la sincronización de subprocesos de Linux

  

Sincronización de subprocesos En la vida real, algunas cosas deben ejecutarse en orden, solo después de que haya terminado, puede continuar con mis resultados de trabajo; no puedo haber terminado todavía Estás empezando a trabajar. Esta es la explicación más directa de la sincronización de hilos.

Lo mismo ocurre cuando se programa. Sincronización de hilos, ¿cuál es la sincronización? Sincroniza el acceso a los recursos compartidos (regiones de memoria, variables públicas, etc.) o regiones críticas. A veces, estos recursos compartidos y áreas críticas solo pueden tolerar un subproceso para operar en él (lectura o escritura, las operaciones de lectura generalmente no están controladas, principalmente operaciones de escritura), en este momento, debemos tener que compartir estos recursos o recursos críticos. Las regiones están sincronizadas, entonces, ¿cómo las sincronizas con los hilos?

Los siguientes dos métodos se proporcionan principalmente en Linux:

Sincronización con semáforos Sincronización con mutex No importa qué método se use, es para la sincronización de subprocesos, y este artículo Un resumen detallado de la sincronización de hilos para semáforos.

¿Cuál es el semáforo primero en descubrir el concepto de semáforos? Un semáforo es un tipo especial de variable que se puede aumentar o disminuir, pero se garantiza que el acceso a él sea una operación atómica, incluso en un programa de multiproceso. Es decir, si dos o más subprocesos en un programa intentan cambiar el valor de un semáforo, el sistema garantizará que todas las operaciones se realicen en secuencia. Si cambia a una variable normal, las operaciones en conflicto de diferentes subprocesos en el mismo programa darán como resultado una operación indeterminada.

En su trabajo, encontrará dos tipos de semáforos: semáforos binarios y semáforos de conteo. El semáforo binario tiene solo dos valores, 0 y 1, mientras que el semáforo cuenta tiene un mayor rango de valores. Si solo se puede acceder a un recurso compartido por un subproceso, el semáforo binario es la mejor idea, si hay varios subprocesos que necesitan acceder al recurso compartido, es una buena idea usar el semáforo de recuento.

La API relacionada con semáforos ha proporcionado algunas interfaces API relacionadas en Linux para implementar semáforos. Primero, combínelas con estas interfaces y luego use un pequeño ejemplo para familiarizarse con la forma de usar estas interfaces.

/*** Crear semáforo * @param setm_t * sem Objeto semáforo, completa inicialización del objeto * @param int pshared El tipo de semáforo; si su valor es 0, significa este semáforo Es el semáforo local del proceso actual; de lo contrario, este semáforo se puede compartir entre múltiples procesos * @param unsigned int value El valor inicial del semáforo * @return int devuelve 0 en caso de éxito; -1 * /int en caso de fallo sem_init (sem_t * sem, int, unsigned int valor pshared); /*** atómicamente cantidad del valor de la señal menos 1 * @param sem_t * objeto semáforo obtenidos sem_init * retornos @return int llamada 0 si tiene éxito; return -1 * /sem_wait (sem_t * sem) fracaso int; /atómicamente *** la cantidad del valor de la señal más 1 * @param sem_t * objeto semáforo llamada sem_init obtenido es exitosa * @return int return 0; return -1 * /int sem_post (sem_t * SEM) fracaso; /*** valor de cuenta del objeto del semáforo del semáforo * @param sem_init obtuvo sem_t * llamada sem * @ param int &realmente devuelto valor El valor del semáforo * @return int devuelve 0 en caso de éxito; -1 * /int en caso de error sem_getvalue (sem_t * sem, int &valor); /*** limpiar todos los recursos del semáforo de propiedad; la cantidad de señal si un intento de limpiar algunas roscas estén en espera, se recibirá un error * @param sem_t * conseguir llamar sem_init un semáforo objeto * @return int exitoso regreso 0; regreso -1 * /int sem_destroy (sem_t * sem) fracaso; se decrementa el valor sem_wait del semáforo, pero se va a esperar hasta que el valor del semáforo es mayor que o igual A las 1 en punto, se inicia la operación de decremento 1. Por lo tanto, si la llamada sem_wait valor del semáforo de 2, el hilo continúa ejecutando; sem_wait mientras que si la señal de funcionamiento es 0, esta función esperará hasta que el otro hilo incrementa el valor del semáforo no es tan Es 0 otra vez.

Se ha introducido una pequeña instancia de las funciones de API para operaciones de semáforo, y ahora use un pequeño programa para usar estas funciones, a través de la codificación real, puede comprender mejor cómo usar estas funciones.

El siguiente paso es completar una función de este tipo:

El hilo principal lee la entrada del terminal de entrada estándar, el hilo secundario 1 convierte la entrada del hilo principal a mayúsculas. Vamos, vamos a implementar el código de acuerdo con las funciones anteriores. Características simples, así que voy a lograr:

En el principal semáforo inicialización hilo es 0; Cuando se introduce el hilo principal, llame sem_post aumentar el valor del semáforo; en el hilo hijo 1, las llamadas sem_wait, esperar a que el semáforo Un valor de 1 reduce el valor del semáforo y luego ejecuta el código en el hilo. Ok, codificándolo.

# include < stdio.h > # include < unistd.h > # include < stdlib.h > # include < pthread.h > # include < semaphore.h > void * ThreadFunc ( void * arg); sem_t sem; #define WORK_SIZE 1024char work_area [WORK_SIZE]; //hilo principal y el hilo hijo para tener acceso a recursos compartidos int main () {int res; pthread_t upperThread; nula threadRes *; res = sem_init (&sem , 0, 0); //semáforo se inicializa a 0

Si (res = 0) {perror (". semáforo falló la inicialización de "); salida (EXIT_FAILURE);}

res = pthread_create (&upperThread, NULL, ThreadFunc, NULL); si (res = 0) {perror (" La creación de hilos fallidos ".); salida (EXIT_FAILURE);} printf (" Por favor introduce convertir texto , luego ingrese 'end' para finalizar. \\ n "); while (strncmp (" end ", work_area, 3)! = 0) {fgets (work_area, WORK_SIZE, stdin); sem_post (&sem); //de entrada es completa, aumente el valor del semáforo int semValue = 0; res = sem_getvalue (&sem, &semValue); //obtener el valor printf semáforo actual (" semáforo recuento:% d \\ n ", semValue); }

printf (" \\ Nwaiting de hilo para terminar ... \\ n "); res = pthread_join (upperThread, &threadRes); if (! res = 0) {perror (" Tema falló y únase quot;.); exit (EXIT_FAILURE);} printf (" Thread join. \\ n "); sem_destroy (&sem); exit (EXIT_SUCCESS);} void * threadFunc (void * arg) {sem_wait (&sem); //reducir el valor del semáforo int semValue = 0; sem_getvalue (&sem, &semValue); printf (" semáforo recuento:% d \\ n ", semValue);

while (strncmp (" final "!, work_area, 3) = 0) {for (int i = 0; work_area [i] = '\\ 0';! ++ i) {if (work_area [i] > = 'a' &&work_area [i] < 'z' =) {work_area [i] = work_area [i] - 32;}}

printf (" Después convtered:% s \\ n ", work_area); sem_wait ( &sem); //Bloquear nuevamente, esperando entrada} pthread_exit (NULL);}

Copyright © Conocimiento de Windows All Rights Reserved