C: Comment déclarer un appel récursif à mutex avec les threads POSIX?
Je suis un peu confus sur la façon de déclarer un appel récursif à pthread mutex en utilisant.
Ce que j'essaie de faire est d'avoir un seul thread à la fois être en mesure d'exécuter un morceau de code(y compris les fonctions), mais après le scepticisme, j'ai réalisé que l'utilisation de mutex ne fonctionnerait pas et qu'au contraire je devrais utiliser récursive mutex. 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
Donc ce que j'essaie de faire est de simplement lire/supprimer de la file d'attente en série.
Le truc, c'est qu'il n'y a pas d'exemple sur la façon de déclarer récursive mutex. Il ya peut-être quelques-uns mais ils ne compile pas pour moi.
- Vous n'avez pas besoin récursive mutex pour les résoudre. L'exemple que vous avez donné est très bien, aussi longtemps que la même
mutex
est utilisée pour tous les threads d'accèsqueue
. Pour cette raison, il serait habituel d'inclure le mutex dans la file d'attente:pthread_mutex_lock(&mutex->queue);
, ou si la file d'attente est opaque structure de données,queue_lock(queue);
(oùqueue_lock()
verrouille le mutex en interne). - L'un des gourous de derrière les pthreads, David Butenhof, a une drôle de récursive mutex diatribe à zaval.org/resources/library/butenhof1.html . Donc oui, récursive les mutex sont généralement une indication d'un défaut de conception.
- Il existe de nombreuses utilisations correctes pour les mutex, mais oui, je vous conseillerais fortement d'un débutant contre eux...
- Je pense qu'il ne sont pas si nombreuses utilisations correctes pour les mutex qui ne peut pas être revue afin de les éviter.
- La classe principale de l'importance de l'utilisation récursive de mutex, que je sache, c'est quand vous avez opérations sur une ressource partagée qui besoin d'être atomique, mais également pour permettre le regroupement de plusieurs opérations d'ensemble, comme une transaction atomique. L'exemple classique est stdio avec
flockfile
.
Vous devez vous connecter pour publier un commentaire.
Le code de Michael Foukarakis est presque bon, mais il initialise le mutex deux fois, ce qui conduit à un comportement indéfini. Il faut juste être:
J'utilise ce code dans la production, et je sais que ça fonctionne correctement sous Linux, Solaris, HP-UX, AIX, Mac OS x et FreeBSD.
Vous devez également ajouter bon linker drapeau pour la compilation:
#define _GNU_SOURCE
(sinon un compilateur renvoie déclaration implicite)main.c:4:24: error: expected declaration specifiers or ‘...’ before ‘&’ token pthread_mutexattr_init(&Attr);
pthread_mutexattr_destroy(&Attr)
à la fin, sinon vous allez être une fuite de mémoire.Pour créer un appel récursif à mutex, utilisation:
où type est
PTHREAD_MUTEX_RECURSIVE
.N'oubliez pas de vérifier la valeur de retour!
Exemple:
ou vous pouvez également initialiser au moment de l'exécution (ne pas faire les deux, c'est un comportement indéterminé):
Sur Linux (mais c'est pas portable vers d'autres systèmes), si le mutex est globale ou statique de la variable, vous pouvez l'initialiser comme
(et par ailleurs, l'exemple est de
pthread_mutex_init(3)
homme pages!)Vous avez besoin d'ajouter des attributs de mutex lors de la création du mutex.
Appel
pthread_mutexattr_init
, puispthread_mutexattr_settype
avecPTHREAD_MUTEX_RECURSIVE
ensuite utiliser ces attributs avecpthread_mutex_init
. Lireman pthread_mutexattr_init
pour plus d'info.