C: Wie deklariert man einen rekursiven Mutex mit POSIX-Threads?
Lesezeit: 4 Minuten
Pithikos
Ich bin etwas verwirrt darüber, wie man einen rekursiven Mutex mit pthread deklariert. Was ich versuche, ist, dass jeweils nur ein Thread einen Code (einschließlich Funktionen) ausführen kann, aber nach Skepsis habe ich herausgefunden, dass die Verwendung von Mutexes nicht funktionieren würde und dass ich stattdessen rekursive Mutexe verwenden sollte. Hier ist mein 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
Also, was ich versuche zu tun, ist einfach seriell aus der Warteschlange zu lesen/entfernen.
Die Sache ist, dass es da draußen kein Beispiel dafür gibt, wie man rekursive Mutexe deklariert. Oder es gibt vielleicht ein paar, aber sie kompilieren nicht für mich.
Sie benötigen keine rekursiven Mutexe, um dies zu lösen. Das Beispiel, das Sie gegeben haben, ist in Ordnung, solange es dasselbe ist mutex wird für alle Threads verwendet, die darauf zugreifen queue. Aus diesem Grund wäre es üblich, den Mutex in die Warteschlange selbst aufzunehmen: pthread_mutex_lock(&mutex->queue);oder wenn die Warteschlange eine undurchsichtige Datenstruktur ist, queue_lock(queue); (wo queue_lock() sperrt den Mutex intern).
– Café
12. August 2011 um 9:08 Uhr
Einer der Gurus hinter pthreads, David Butenhof, hat einen amüsanten rekursiven Mutex-Geschwätz zaval.org/resources/library/butenhof1.html . Also ja, rekursive Mutexe sind normalerweise ein Hinweis auf ein fehlerhaftes Design.
– janeb
12. August 2011 um 9:29 Uhr
@janneb: Es gibt viele korrekte Verwendungen für rekursive Mutexe, aber ja, ich würde einem Anfänger dringend davon abraten …
– R.. GitHub HÖR AUF, EIS ZU HELFEN
12. August 2011 um 12:18 Uhr
@R ..: Ich denke, es gibt nicht so viele korrekte Verwendungen für rekursive Mutexe, die nicht neu gestaltet werden können, um sie zu vermeiden.
– Andriy Tylychko
30. Oktober 2011 um 11:07 Uhr
@AndyT: Die Hauptklasse wichtiger Anwendungen für rekursive Mutexe, die ich kenne, ist, wenn Sie Operationen auf einer gemeinsam genutzten Ressource haben, die einzeln atomar sein müssen, aber auch das Gruppieren mehrerer Operationen als atomare Transaktion zulassen möchten. Das klassische Beispiel ist stdio with flockfile.
– R.. GitHub HÖR AUF, EIS ZU HELFEN
30. Oktober 2011 um 21:48 Uhr
Piotr Kukielka
Der Code von Michael Foukarakis ist fast gut, aber er initialisiert den Mutex zweimal, was zu undefiniertem Verhalten führt. Es sollte nur sein:
Ich verwende diesen Code tatsächlich in der Produktion und ich weiß, dass er unter Linux, Solaris, HP-UX, AIX, Mac OSX und FreeBSD korrekt funktioniert.
Sie müssen auch das richtige Linker-Flag hinzufügen, um dies zu kompilieren:
oder alternativ zur Laufzeit initialisieren (nicht beides tun, es ist undefiniertes Verhalten):
pthread_mutexattr_init(&mta);
/* or PTHREAD_MUTEX_RECURSIVE_NP */
pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mutex, &mta);
Ich bekomme den Fehler, den ich in meinen früheren Versuchen bekommen habe. Die Zeilen, die nicht kompiliert werden, sind die drei letzten, und ich verwende GCC mit dem Flag -pthread. pthread.h ist ebenfalls enthalten.
– Pithikos
12. August 2011 um 8:49 Uhr
Welcher Fehler? Du hast nie einen erwähnt. Überprüfen Sie auf jeden Fall die aktualisierte Antwort.
– Michael Foukarakis
12. August 2011 um 8:52 Uhr
Ja, welcher Fehler tatsächlich und welches Betriebssystem? Solaris erfordert [g]cc -mt für Multithread-Anwendungen. Einige Implementierungen von “pthreads” sind nicht 100 % POSIX-kompatibel.
– Jim Mcnamara
31. Oktober 2011 um 14:47 Uhr
Wenn der Mutex unter Linux (aber nicht auf andere Systeme portierbar) eine globale oder statische Variable ist, können Sie ihn wie folgt initialisieren
(Das Beispiel stammt übrigens von pthread_mutex_init(3)Mann Seiten!)
Danke für die Information. So fand ich auf MAC es ist: static pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
– Val
11. November 2014 um 8:46 Uhr
Beim Erstellen des Mutex müssen Sie Mutex-Attribute hinzufügen.
Anruf pthread_mutexattr_initdann pthread_mutexattr_settype mit PTHREAD_MUTEX_RECURSIVE Verwenden Sie dann diese Attribute mit pthread_mutex_init. Lesen man pthread_mutexattr_init Für mehr Information.
14116400cookie-checkC: Wie deklariert man einen rekursiven Mutex mit POSIX-Threads?yes
Sie benötigen keine rekursiven Mutexe, um dies zu lösen. Das Beispiel, das Sie gegeben haben, ist in Ordnung, solange es dasselbe ist
mutex
wird für alle Threads verwendet, die darauf zugreifenqueue
. Aus diesem Grund wäre es üblich, den Mutex in die Warteschlange selbst aufzunehmen:pthread_mutex_lock(&mutex->queue);
oder wenn die Warteschlange eine undurchsichtige Datenstruktur ist,queue_lock(queue);
(woqueue_lock()
sperrt den Mutex intern).– Café
12. August 2011 um 9:08 Uhr
Einer der Gurus hinter pthreads, David Butenhof, hat einen amüsanten rekursiven Mutex-Geschwätz zaval.org/resources/library/butenhof1.html . Also ja, rekursive Mutexe sind normalerweise ein Hinweis auf ein fehlerhaftes Design.
– janeb
12. August 2011 um 9:29 Uhr
@janneb: Es gibt viele korrekte Verwendungen für rekursive Mutexe, aber ja, ich würde einem Anfänger dringend davon abraten …
– R.. GitHub HÖR AUF, EIS ZU HELFEN
12. August 2011 um 12:18 Uhr
@R ..: Ich denke, es gibt nicht so viele korrekte Verwendungen für rekursive Mutexe, die nicht neu gestaltet werden können, um sie zu vermeiden.
– Andriy Tylychko
30. Oktober 2011 um 11:07 Uhr
@AndyT: Die Hauptklasse wichtiger Anwendungen für rekursive Mutexe, die ich kenne, ist, wenn Sie Operationen auf einer gemeinsam genutzten Ressource haben, die einzeln atomar sein müssen, aber auch das Gruppieren mehrerer Operationen als atomare Transaktion zulassen möchten. Das klassische Beispiel ist stdio with
flockfile
.– R.. GitHub HÖR AUF, EIS ZU HELFEN
30. Oktober 2011 um 21:48 Uhr