Programación multiproceso de Linux (2) 2019-08-10
Hay tres mecanismos dedicados a la sincronización de subprocesos: semáforos POSIX, mutex y variables de condición.
Hay dos grupos de API de semáforos en Linux, uno es el semáforo System V IPC, es decir. , operación PV y semáforo POSIX Los nombres de los semáforos POSIX comienzan con sem_.
El parámetro phshared especifica el tipo de semáforo. Si su valor es 0, significa que el semáforo es un semáforo local. de lo contrario, el semáforo se puede compartir entre varios procesos. El valor especifica el valor inicial del semáforo, que generalmente corresponde a la función sem_wait a continuación
Entre ellas, la función más importante sem_wait. reduzca el valor del semáforo en uno en una operación atómica. Si el valor del semáforo es cero, sem_wait se bloqueará. El valor del semáforo se puede inicializar por el valor en la función sem_trywait. de sem_wait; la función sem_post agregará uno al semáforo en una operación atómica. Cuando el valor del semáforo es mayor que 0, se despertarán otros subprocesos que estén llamando a sem_wait y esperando el semáforo.
Estas funciones devuelven 0 cuando tienen éxito y -1 y establecen errno si fallan.
Modelo productor-consumidor:
El productor corresponde a un semáforo: sem_t productor;
El consumidor corresponde a un semáforo: sem_t cliente;
sem_init(&producer,2)----El productor tiene recursos y puede trabajar;
sem_init(&customer,0 )----El consumidor no tiene recursos y está bloqueado;
Establezca (bloquee) el mutex antes de acceder al recurso público para garantizar que solo un hilo acceda a los datos al mismo tiempo después del acceso. completado Luego libere (desbloquee) el mutex.
El modo de operación del bloqueo mutex: acceso en serie a recursos compartidos;
El modo de operación del semáforo: acceso paralelo*** Compartido recursos;
El mutex está representado por el tipo de datos pthread_mutex_t. Antes de usar el mutex, debe inicializarse usando la función pthread_mutex_init. Tenga en cuenta que pthread_mutex_destroy debe llamarse después de su uso. pthread_mutex_init se usa para inicializar el bloqueo mutex y mutexattr se usa para especificar los atributos del bloqueo mutex. Si es NULL, indica el atributo predeterminado. Además de utilizar esta función para inicializar el mutex, también puede inicializarlo de la siguiente manera: pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER.
pthread_mutex_destroy se utiliza para destruir el bloqueo mutex y liberar los recursos del núcleo ocupados. Destruir un bloqueo mutex ya bloqueado tendrá consecuencias impredecibles.
pthread_mutex_lock bloquea un mutex en una operación atómica. Si el bloqueo mutex de destino ya está bloqueado, pthread_mutex_lock se bloquea hasta que el propietario del bloqueo mutex lo desbloquee.
pthread_mutex_trylock es similar a pthread_mutex_lock, pero siempre regresa inmediatamente, independientemente de si el mutex es. bloqueado es una versión sin bloqueo de pthread_mutex_lock. Cuando el mutex de destino no está bloqueado, pthread_mutex_trylock realiza la operación de bloqueo; de lo contrario, se devolverá el código de error EBUSY.
Nota: pthread_mutex_lock y pthread_mutex_trylock que se analizan aquí son para bloqueos ordinarios. Para otros tipos de bloqueos, estas dos funciones de bloqueo tendrán comportamientos diferentes.
pthread_mutex_unlock le da a un mutex una operación atómica. El bloqueo está desbloqueado. Si hay otros subprocesos esperando este mutex en este momento, uno de estos subprocesos lo adquirirá.
Las tres impresoras se turnan para imprimir:
Salida. resultado:
Si el mutex se usa para sincronizar el acceso de los subprocesos a datos compartidos, entonces la variable de condición se usa para sincronizar el valor de los datos compartidos entre subprocesos. Las variables de condición proporcionan un mecanismo para la comunicación entre subprocesos: cuando. ciertos datos compartidos alcanzan un cierto valor, el hilo que espera los datos compartidos se despierta.
Las variables de condición se utilizarán cuando las condiciones sean diferentes. Bloquea el hilo cuando se cumplen. se utilizan juntos para permitir que los subprocesos esperen a que ocurran condiciones específicas sin competencia.
Entre ellos, la función pthread_cond_broadcast activa todas las variables de condición de destino en espera en forma de subproceso de transmisión, y la función pthread_cond_signal es. se utiliza para despertar un hilo que espera la variable de condición de destino, pero a veces es posible que necesitemos despertar un hilo fijo, lo que se puede lograr mediante métodos indirectos: definir una variable global que pueda identificar de forma única el hilo de destino y despertar el hilo en espera. variable de condición Establezca esta variable como el subproceso de destino antes del subproceso y luego use la transmisión para activar todos los subprocesos en espera. Una vez que estos subprocesos se despierten, verificarán la variable para determinar si son ellos mismos.
Usar. variables de condición + bloqueo de exclusión mutua implementa el modelo productor-consumidor:
Resultados de ejecución:
Cola de bloqueo + productor-consumidor
Resultados de ejecución: