Wie überprüfe ich, ob ein Thread in Rust fertig ist?

8

Wenn ich spawn ein Thread in Rust habe, bekomme ich JoinHandle , was gut ist für ... (eine blockierende Operation) und nicht viel mehr. Wie kann ich überprüfen, ob ein untergeordneter Thread aus dem übergeordneten Thread beendet wurde (d. H.% Co_de% würde nicht blockieren)? Bonuspunkte, wenn Sie wissen, wie Sie einen Kinder-Thread töten können.

Ich kann mir vorstellen, dass Sie dies tun können, indem Sie einen Kanal erstellen, etwas an das Kind senden und Fehler abfangen, aber das scheint unnötige Komplexität und Overhead zu sein.

    
Doctor J 09.03.2016, 05:11
quelle

3 Antworten

8

Ab Rust 1.7 gibt es in der Standardbibliothek keine API, um zu überprüfen, ob ein untergeordneter Thread ohne Blockierung beendet wurde.

Eine portable Problemumgehung wäre die Verwendung von Channels , um eine Nachricht vom untergeordneten Element zu senden der Elternteil, um zu signalisieren, dass das Kind aussteigen wird. Receiver hat eine nicht blockierende try_recv Methode. Wenn try_recv eine Nachricht empfängt, können Sie join() für JoinHandle verwenden, um das Ergebnis des Threads abzurufen.

Es gibt auch instabile plattformspezifische Erweiterungsmerkmale, mit denen Sie den rohen Thread-Handle erhalten können. Sie müssten dann plattformspezifischen Code schreiben, um zu testen, ob der Thread beendet wurde oder nicht.

Wenn Sie der Ansicht sind, dass diese Funktion in Rusts Standardbibliothek enthalten sein soll, können Sie einen RFC einreichen (achten Sie darauf, die README zuerst!).

  

Bonuspunkte, wenn Sie wissen, wie Sie einen untergeordneten Thread töten können.

Threads in Rust werden mit nativen OS-Threads implementiert. Auch wenn das Betriebssystem eine Möglichkeit bietet, einen Thread zu beenden, ist es eine schlechte Idee, dies zu tun, da die Ressourcen, die dem Thread zugewiesen wurden, erst nach dem Prozess endet.

    
Francis Gagné 09.03.2016 05:39
quelle
8

Die kurze Antwort ist noch nicht möglich. Aber das ist nicht der Punkt, der wirklich angesprochen werden sollte.

  

Bonuspunkte, wenn Sie wissen, wie Sie einen untergeordneten Thread töten können.

NIE

Sogar in Sprachen, die das Löschen von Threads unterstützen ( siehe Java hier ), es wird empfohlen, dies nicht zu tun.

Die Ausführung eines Threads wird im Allgemeinen mit expliziten Interaktionspunkten codiert, und es gibt oft implizite Annahmen , dass keine andere Unterbrechung auftreten wird.

Das ungeheuerlichste Beispiel sind natürlich Ressourcen: Die naive "Kill" -Methode wäre, den Thread nicht mehr auszuführen; Dies würde bedeuten, keine Ressource freizugeben. Du denkst vielleicht an die Erinnerung, es ist die geringste deiner Sorgen. Stellen Sie sich stattdessen alle Mutex vor, die nicht entsperrt sind und später Deadlocks erzeugen ...

Die andere Möglichkeit wäre, ein panic in den Thread zu injizieren, was zu einem Abwickeln führen würde. Sie können jedoch nicht nur beginnen, sich zu irgendeinem Zeitpunkt zu entspannen! Das Programm müsste sichere Punkte definieren, bei denen die Injektion von panic garantiert sicher wäre (die Injektion an einem anderen Punkt bedeutet möglicherweise die Beschädigung gemeinsamer Objekte); Wie man solche sicheren Punkte definiert und das panic injiziert, gibt es ein offenes Forschungsproblem in nativen Sprachen, besonders auf Systemen W^X (wo Speicherseiten entweder Writable oder Executable sind, aber nie beides).

Zusammenfassend ist nicht bekannt, dass ein Thread (sowohl speicher- als auch funktional) sicher beendet werden kann.

    
Matthieu M. 09.03.2016 09:21
quelle
2

Es ist möglich, Freunde. Verwenden Sie refcounters , die Rust auf Ende oder panic fallen lässt. 100% sicher. Beispiel:

%Vor%

Gist: Ссылка

Auf dem Spielplatz: Ссылка

UPD : Ich habe thread-control crate erstellt, das diesen Ansatz implementiert: Ссылка

    
DenisKolodin 21.09.2016 11:23
quelle

Tags und Links