pseint - C: ¿Cómo declara un mutex recursivo con subprocesos POSIX?
busqueda binaria pseint (4)
Estoy un poco confundido sobre cómo declarar un mutex recursivo usando pthread. Lo que trato de hacer es que solo un hilo a la vez pueda ejecutar un fragmento de código (incluidas las funciones), pero después del escepticismo descubrí que el uso de mutexes no funcionaría y que, en cambio, debería usar mutex recursivos. Aquí está mi código:
pthread_mutex_lock(&mutex); // LOCK
item = queue_peek(queue); // get last item in queue
item_buff=item; // save item to a buffer
queue_removelast(queue); // remove last item from queue
pthread_mutex_unlock(&mutex); // UNLOCK
Entonces, lo que trato de hacer es leer / eliminar de la cola en serie.
La cuestión es que no hay ningún ejemplo sobre cómo declarar mutex recursivos. O quizás unos pocos pero no compilan para mí.
Debe crear atributos mutex al crear el mutex.
Llame a pthread_mutexattr_init
, luego pthread_mutexattr_settype
con PTHREAD_MUTEX_RECURSIVE
luego use estos atributos con pthread_mutex_init
. Lee man pthread_mutexattr_init
para más información.
El código de Michael Foukarakis es casi bueno, pero inicializa el mutex dos veces, lo que conduce a un comportamiento indefinido. Debería ser así:
pthread_mutex_t Mutex;
pthread_mutexattr_t Attr;
pthread_mutexattr_init(&Attr);
pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&Mutex, &Attr);
Utilizo este código en la producción y sé que funciona correctamente en Linux, Solaris, HP-UX, AIX, Mac OSX y FreeBSD.
/editar
También es necesario agregar un indicador de vinculador adecuado para compilar esto.
AIX, Linux, FreeBSD:
CPLATFORM + = -pthread
mingw32:
LDFLAGS + = -lpthread
En Linux (pero esto no es portátil a otros sistemas), si el mutex es una variable global o estática, podría inicializarlo como
static pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
(y, por cierto, el ejemplo es de pthread_mutex_init(3)
páginas de manual)
Para crear un mutex recursivo, use:
#include <pthread.h>
int pthread_mutexatttr_settype(pthread_mutexattr_t *attr,
int type);
donde tipo es PTHREAD_MUTEX_RECURSIVE
.
No te olvides de comprobar el valor de retorno!
Ejemplo:
/* or PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutexattr_t mta;
o alternativamente, inicialice en tiempo de ejecución (no haga ambas cosas, es un comportamiento indefinido):
pthread_mutexattr_init(&mta);
/* or PTHREAD_MUTEX_RECURSIVE_NP */
pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mutex, &mta);