Ich habe zwei Threads, einen, der in einer engen Schleife arbeitet, und den anderen, der gelegentlich eine Synchronisation mit dem ersten durchführt:
%Vor%Meine Absicht ist, dass Thread 2, indem er die Sperre nimmt, effektiv Thread 1 pausiert und die notwendige Synchronisation durchführt. Thread 1 kann auch anbieten, durch Entriegeln zu pausieren, und wenn Thread 2 nicht auf Sperren wartet, erneut sperren und zur Arbeit zurückkehren.
Das Problem, auf das ich gestoßen bin, ist, dass Mutexe nicht fair sind, also sperrt Thread 1 schnell den Mutex und verharmlosen Thread 2. Ich habe versucht, pthread_yield
zu benutzen, und bisher scheint es in Ordnung zu laufen, aber ich bin es nicht sicher, dass es für alle Systeme / Anzahl der Kerne funktioniert. Gibt es eine Möglichkeit zu garantieren, dass Thread 1 auch bei Multi-Core-Systemen immer Thread 2 liefert?
Was ist der effektivste Weg, diesen Synchronisationsprozess zu verarbeiten?
Sie können eine FIFO- "Ticket-Sperre" über Pthreads-Mutexen in folgenden Zeilen erstellen:
%Vor%Bei dieser Art von Schema wird kein low-level pthreads-Mutex gehalten, während sich ein Thread innerhalb des ticketlock-geschützten kritischen Abschnitts befindet, wodurch andere Threads der Warteschlange beitreten können.
In deinem Fall ist es besser, die Bedingungsvariable zu verwenden, um den zweiten Thread zu benachrichtigen, wenn es aktiviert werden muss und führe alle erforderlichen Operationen durch.
pthread
bietet eine Vorstellung von Thread-Priorität in seiner API. Wenn zwei Threads über einen Mutex konkurrieren, bestimmt die Planungsrichtlinie , welche Version sie erhält. Mit der Funktion pthread_attr_setschedpolicy
können Sie das festlegen und mit pthread_attr_getschedpolicy
können Sie die Informationen abrufen.
Jetzt die schlechten Nachrichten:
SCHED_FIFO
, SCHED_RR
, SCHED_OTHER
und SCHED_SPORADIC
), aber In dieser Frage wurde geantwortet, dass nur SCHED_OTHER
auf Linux unterstützt wurde) Also würde ich es versuchen, wenn ich du wäre, aber nicht zu viel erwarten. pthread_yield
erscheint mir vielversprechender. Weitere Informationen finden Sie hier .
Hier ist eine einfache Lösung, die für Ihren Fall (zwei Threads) funktioniert. Wenn Sie std::mutex
verwenden, ist diese Klasse ein Drop-In-Ersatz. Ändern Sie Ihren Mutex auf diesen Typ und Sie werden garantiert, dass wenn ein Thread die Sperre hält und die andere darauf wartet, sobald der erste Thread entsperrt, der zweite Thread die Sperre ergreift, bevor der erste Thread sie wieder sperren kann.
Wenn mehr als zwei Threads gleichzeitig den Mutex benutzen, funktioniert es immer noch, aber es gibt keine Garantie für Fairness.
Wenn Sie plain pthread_mutex_t
verwenden, können Sie Ihren Sperrcode gemäß diesem Beispiel einfach ändern (Entsperren bleibt unverändert).
Tags und Links c++ multithreading pthreads