Usa mutexes para controlar la sincronización de hilos de Linux

  
 

¿Qué es un mutex?

Un mutex es un método para el acceso sincrónico en multiproceso que permite que un programa bloquee un objeto o un fragmento de código para que solo pueda haber uno a la vez. Un hilo lo accede. Para controlar el acceso a objetos o códigos clave, debe bloquear un mutex antes de ingresar este código y luego desbloquearlo después de completar la operación. Su esencia es la misma que el semáforo, es una operación P /V.

Falta las API relacionadas.

Para el aprendizaje de exclusión mutua, no puede hacerlo sin el aprendizaje de varias API. Antes de comenzar a codificar para obtener una DEMO pequeña, echemos un vistazo a estas. Función API. /*** Inicializa un mutex * @param mutex * El mutex que finalmente se inicializa * @param mutexattr * La propiedad del mutex * @return devuelve 0 en caso de éxito; de lo contrario, devuelve un código de error distinto de cero, pero no se establece Errno error valor * /int pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * mutexattr);

/*** Mutex para la operación de bloqueo * @param mutex * Mutex para pthread_mutex_init * @ Devolver devuelve 0 si es exitoso; de lo contrario, devuelve un código de error distinto a cero, pero no establece el valor de error errno * /int pthread_mutex_lock (pthread_mutex_t * mutex);

/*** Mutex para desbloquear la operación * @param Mutex * El mutex obtenido por pthread_mutex_init * @return devuelve 0 en caso de éxito; de lo contrario, devuelve un código de error distinto de cero, pero no establece el valor de error errno * /int pthread_mutex_unlock (pthread_mutex_t * mutex);

/* ** Versión no bloqueante de la función pthread_mutex_lock. * Si el mutex especificado por el parámetro mutex ya está bloqueado, * llamar a la función pthread_mutex_trylock no bloquea el subproceso actual, pero devuelve inmediatamente un valor que describe la condición del mutex. * @param mutex Mutex obtenido por pthread_mutex_init * @return devuelve 0 en caso de éxito; de lo contrario, devuelve un código de error distinto de cero, pero no establece el valor de error errno * /int pthread_mutex_trylock (pthread_mutex_t * mutex);

/*** Destruye el mutex creado * @param mutex * El mutex obtenido por pthread_mutex_init * @return devuelve 0 en caso de éxito; de lo contrario, devuelve un código de error distinto de cero, pero no establece el valor de error errno * /int pthread_mutex_destroy ( Pthread_mutex_t * mutex);

Una pequeña instancia

Bueno, la introducción de las funciones de la API siempre es muy seca, para señalar el código de productos secos, para ver cómo usar la exclusión mutua. A continuación quiero codificar para lograr las siguientes tareas: • el hilo principal puede ingresar letras de manera continua, cuando se ingresa el final, el programa termina; • el hilo secundario convierte las letras ingresadas por el hilo principal en mayúsculas;

el hilo principal puede La entrada estándar se ingresa constantemente y el subproceso secundario se puede convertir continuamente. No, directamente en el código, el código es un poco más largo, por favor léalo cuidadosamente. #include < stdio.h > #include < unistd.h > #include < stdlib.h &#gt; #include < string.h < #include < pthread.h > >

void * threadFunc (void * arg); pthread_mutex_t work_mutex; sem_t sem;

#define WORK_SIZE 1024char work_area [WORK_SIZE];

int main () {int st; pthread_t res1; void * threadRes;

res = pthread_mutex_init (&work_mutex, NULL); //Inicializar el mutex if (res! = 0) {perror (" Falló la inicialización de Mutex. "); exit ( EXIT_FAILURE);}

res = sem_init (&sem, 0, 0); if (res! = 0) {perror (" Semaphore create failed. &Quot;); exit (EXIT_FAILURE);} < Br>

res = pthread_create (&thread1, NULL, threadFunc, NULL); if (res! = 0) {perror (" Thread crea error. &Quot;); exit (EXIT_FAILURE);}

printf (" Ingrese texto. Ingrese 'end' para finalizar. \\ n "); pthread_mutex_lock (&​​amp; work_mutex); while (strncmp (work_area, quot; fin ", 3)! = 0) {fgets (work_area , WORK_SIZE, stdin); pthread_mutex_unlock (&​​amp; work_mutex); sem_wait (&a Mp; sem); //tell thread 1, mi información está terminada, es su turno de procesar, dígame después de procesar

pthread_mutex_lock (&​​amp; work_mutex);} pthread_mutex_unlock (&​​amp; work_mutex); Br>

printf (" \\ nEsperando que el hilo termine ... \\ n "); res = pthread_join (thread1, &threadRes); if (res! = 0) {perror (" Error en la combinación de hilos. "); exit (EXIT_FAILURE);}

printf (" Thread joined. \\ n "); pthread_mutex_destroy (&work_mutex); sem_destroy (&sem); exit (EXIT_SUCCESS);}

void * threadFunc (void * arg) {pthread_mutex_lock (&​​amp; work_mutex); while (strncmp (work_area, end ", 3)! = 0) {if (work_area [0]! = '\\ 0' ) {for (int i = 0; área_trabajo [i]! = '\\ 0'; ++ i) {if (área_trabajo [i] > = 'a' &&work_area [i] < = 'z ') {work_area [i] - =' a '-' A ';}}

printf (" Después de convertir:% s \\ n ", work_area); sem_post (&sem); //Dile al hilo principal, terminé de procesar, es tu turno de leer el memset de datos (área_trabajo, 0, sizeof (área_trabajo));} pthread_mutex_unlock (&​​amp; work_mutex); sleep (1); pthread_mutex_lock (&​​amp; work_mutex);}

pthread_mutex_unlock (&​​amp; work_mutex); sem_post (&sem); pthread_exit (NULL);}

La tarea está completa, no está mal. Sin embargo, es muy difícil garantizar la sincronización en el desarrollo de subprocesos múltiples. No mire el código anterior para completar la tarea, es muy simple, pero muchos pozos, es decir, ahora, no puedo garantizar que el código anterior sea 100% sin pozos, solo esperando que elija.

¿Por qué es tan difícil la sincronización de subprocesos múltiples? Intuitivamente, el cerebro humano es de un solo hilo. Si quieres ir a múltiples hilos y pensar en muchas cosas, estarás confundido. Al igual que, deja que tu mano izquierda dibuje un círculo, la mano derecha dibuja un cuadrado, ¿puedes dibujar uno perfecto? La razón es muy simple, piense más, escriba más, complete más pozos. Chicos

Copyright © Conocimiento de Windows All Rights Reserved