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.

40
demandé sur jotik 2011-08-12 12:30:31

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

73
répondu Piotr Kukielka 2011-11-01 08:01:25

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);
16
répondu Michael Foukarakis 2013-08-17 09:56:34

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!)

13
répondu Basile Starynkevitch 2011-10-28 19:42:53

vous devez ajouter des attributs mutex lors de la création du mutex.

Appel pthread_mutexattr_init, puis pthread_mutexattr_settypePTHREAD_MUTEX_RECURSIVE ensuite utiliser ces attributs pthread_mutex_init. Lire man pthread_mutexattr_init pour plus d'info.

2
répondu hamstergene 2011-08-12 08:37:31