pthreads: Thread-Hunger durch schnelles erneutes Sperren

8

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?

    
scientiaesthete 02.10.2012, 05:46
quelle

5 Antworten

3

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.

    
caf 03.10.2012, 07:12
quelle
5

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.

    
Sergei Nikulov 02.10.2012 06:13
quelle
2

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:

  • Wenn nur zwei Threads einen Mutex sperren / entsperren, kann ich keine Konkurrenz sehen, der erste, der den atomaren Befehl ausführt, nimmt ihn, die anderen Blöcke. Ich bin mir nicht sicher, ob dieses Attribut hier gilt.
  • Die Funktion kann verschiedene Parameter annehmen ( 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 .

    
qdii 02.10.2012 06:36
quelle
0

Das Ticketschloss oben sieht am besten aus. Um sicherzustellen, dass Ihr pthread_yield funktioniert, können Sie jedoch ein Bool warten, das von thread2 gesetzt und zurückgesetzt wird. thread1 gibt an, solange bool waiting gesetzt ist.

    
edW 16.09.2013 14:19
quelle
0

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

%Vor%     
itaych 24.10.2017 08:37
quelle

Tags und Links