2009-09-01 6 views
5

Der Mac-Build meiner (hauptsächlich POSIX) Anwendung erzeugt einen untergeordneten Thread, der CFRunLoopRun() aufruft, um eine Ereignisschleife auszuführen (um Änderungen der Netzwerkkonfiguration von MacOS zu erhalten).Ist es sicher, CFRunLoopStop von einem anderen Thread aufzurufen?

Wenn es an der Zeit ist, Dinge zu packen und wegzugehen, ruft der Hauptthread CFRunLoopStop() in der Run-Schleife des untergeordneten Threads auf. An diesem Punkt gibt CFRunLoopRun() den untergeordneten Thread, den untergeordneten Thread und den main zurück Der Thread (der blockierte und darauf wartete, dass der untergeordnete Thread beendet wird) kann fortgesetzt werden.

Dies scheint zu funktionieren, aber meine Frage ist: Ist dies eine sichere/empfohlene Möglichkeit, es zu tun? Insbesondere wird CFRunLoopStop() von einem anderen Thread aufgerufen, der einen Racebedingung verursachen kann? Apples Dokumentation schweigt zu dem Thema, soweit ich das beurteilen kann.

Wenn CFRunLoopStop() aus dem Hauptthread aufrufen nicht die Lösung ist, was ist eine gute Lösung? Ich weiß, dass ich den untergeordneten Thread CFRunLoopRunInMode aufrufen() und aufwachen könnte, um einen booleschen Wert oder etwas zu überprüfen, aber ich würde es vorziehen, wenn der untergeordnete Thread keine Abfrage durchführen würde, wenn ich es vermeiden kann.

Antwort

2

Insbesondere ruft CFRunLoopStop() von einem anderen Thread [sicher]?

Hier ist, was Run Loop Management sagt:

Die Funktionen in Core Foundation sind in der Regel Thread-sicher und kann von jedem Thread aufgerufen werden.

Also ist CFRunLoopStop sicher. Aber ich mache mir Sorgen über ihre Verwendung des Wortes "allgemein". Meine Regel lautet: Wenn Apple nicht sagt, dass es sicher ist, solltest du davon ausgehen, dass es nicht so ist.

Um auf der sicheren Seite zu bleiben, könnten Sie in Betracht ziehen, eine Run-Loop-Quelle zu erstellen, diese zu Ihrer Run-Schleife hinzuzufügen und diese Quelle zu signalisieren, wenn es Zeit ist, den Thread zu beenden. Dasselbe Dokument enthält ein Beispiel für eine benutzerdefinierte Run-Loop-Quelle.

11

Im Fall von CFRunLoopStop - wenn es nur sicher auf der aktuellen Laufschleife aufgerufen werden könnte, dann wäre es nicht notwendig, einen Parameter zu übergeben, der angibt, welche Laufschleife gestoppt werden soll.

Das Vorhandensein des Parameters ist ein starkes Anzeichen dafür, dass es in Ordnung ist, es zu verwenden, um andere Lauf-Schleifen als die aktuelle Lauf-Schleife zu stoppen.