C: Comment déclarer un mutex récursif avec des threads POSIX?
je suis un peu confus sur la façon de déclarer un mutex récursif en utilisant pthread. Ce que j'essaie de faire est de n'avoir qu'un seul thread à la fois pour pouvoir exécuter un morceau de code(y compris les fonctions) mais après le scepticisme, j'ai compris que l'utilisation de mutex ne fonctionnerait pas et qu'à la place je devrais utiliser des Mutex récursifs. Voici mon code:
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
alors ce que j'essaie de faire c'est simplement de lire/Supprimer de la file d'attente.
Le truc, c'est qu'il n'y a pas d'exemple sur la façon de déclarer récursive mutex. Ou il y en a peut-être quelques-uns mais ils ne compilent pas pour moi.
4 réponses
le Code de Michael Foukarakis est presque bon mais il initialise mutex deux fois ce qui conduit à un comportement non défini. Il devrait être comme ça:
pthread_mutex_t Mutex;
pthread_mutexattr_t Attr;
pthread_mutexattr_init(&Attr);
pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&Mutex, &Attr);
j'utilise acutally ce code dans la production, et je sais qu'il fonctionne correctement sur Linux, Solaris, HP-UX, AIX, Mac OSX et FreeBSD.
/ edit
Vous avez aussi besoin d'ajouter le drapeau de linker approprié pour compiler ceci.
AIX, Linux, FreeBSD:
CPLATFORM += - pthread
mingw32:
LDFLAGS + = - lpthread
pour créer un mutex récursif, utilisez:
#include <pthread.h>
int pthread_mutexatttr_settype(pthread_mutexattr_t *attr,
int type);
où le type est PTHREAD_MUTEX_RECURSIVE
.
N'oubliez pas de vérifier la valeur de retour!
Exemple:
/* or PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutexattr_t mta;
ou sinon, initialiser à l'exécution (ne pas faire les deux, c'est un comportement non défini):
pthread_mutexattr_init(&mta);
/* or PTHREAD_MUTEX_RECURSIVE_NP */
pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mutex, &mta);
sous Linux (mais non portable vers d'autres systèmes), si le mutex est une variable globale ou statique, vous pouvez l'initialiser comme
static pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
(et par ailleurs, l'exemple est de pthread_mutex_init(3)
homme pages!)
vous devez ajouter des attributs mutex lors de la création du mutex.
Appel pthread_mutexattr_init
, puis pthread_mutexattr_settype
PTHREAD_MUTEX_RECURSIVE
ensuite utiliser ces attributs pthread_mutex_init
. Lire man pthread_mutexattr_init
pour plus d'info.