std :: Versprechender externer Code, asynchrone Löschung

8

Angenommen, Sie haben einen externen synchronen Code, den Sie nicht ändern können, und Sie benötigen ihn für die Ausführung von async, müssen ihn aber auch abbrechen können. Wenn der externe Code blockiert, habe ich zwei Möglichkeiten.

A) Machen Sie den Benutzer täuschend und lassen Sie meine Async-Methode sofort nach dem Abbruch zurückkehren. Dabei ist mir bewusst, dass der Code irgendwo noch immer ausgeführt wird.

B) Ausführung abbrechen

Ich würde gerne eine Schnittstelle für Option B implementieren

%Vor%

Im obigen Code kann ich mich nicht mit der Einschränkung des blockierenden externen Codes herumschlagen, wie kann ich, wenn überhaupt, die Ausführung vorzeitig abbrechen?

    
arynaq 20.12.2017, 14:30
quelle

3 Antworten

5

Kurze Antwort:

Beenden / beenden Sie die Thread-Ausführung nicht, es sei denn, sie ist unternehmenskritisch. Verwenden Sie stattdessen "A".

Lange Antwort:

Wie @Caleth bemerkt hat, gibt es keinen standardmäßigen oder plattformübergreifenden Weg, dies zu tun. Alles, was Sie tun können, ist, ein natives Handle zu einem Thread zu bekommen und eine plattformspezifische Funktion zu verwenden. Aber es gibt einige wichtige Grubenstürze.

win32

Sie können einen Thread mit TerminateThread Funktion, aber:

  • Stack-Variablen werden nicht zerstört
  • thread_local Variablen werden nicht zerstört
  • DLLs werden nicht benachrichtigt

MSDN sagt:

  

TerminateThread ist eine gefährliche Funktion, die nur in verwendet werden sollte   die extremsten Fälle.

Pthread

Hier ist die Situation etwas besser. Sie haben die Möglichkeit, Ihre Ressourcen freizugeben, wenn pthread_cancel aufgerufen wird, aber:

  • Standardmäßig endet der Ziel-Thread auf Abbruchpunkten . Dies bedeutet, dass Sie einen Code nicht stornieren können, der keinen Abbruchspunkt hat. Grundsätzlich wird for(;;); nicht abgebrochen .
  • Sobald der Abbruchpunkt erreicht ist, wird eine implementierungsspezifische Ausnahme ausgelöst, sodass Ressourcen ordnungsgemäß freigegeben werden können.
  • Beachten Sie, dass diese Ausnahme von try / catch abgefangen werden kann, aber sie muss erneut geworfen werden.
  • Dieses Verhalten kann von pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, nullptr); deaktiviert werden. Wenn der Abbruchpunkt jedoch nicht erreicht wird, werden die Ressourcen nicht freigegeben (wie für win32 )

Beispiel

%Vor%

Sie können das sehen:

  • Der Destruktor wird niemals in Windows aufgerufen.
  • Das Entfernen von pthread_setcanceltype führt zum Hängen.
  • Die interne pthread -Ausnahme konnte abgefangen werden.
ivaigult 26.12.2017 11:17
quelle
2

Es gibt keine Möglichkeit, einen Thread vorzeitig zu beenden.

Abhängig von Ihrer Plattform können Wege sein, einen Thread zu beenden, für den Sie wahrscheinlich std::thread::native_handle verwenden müssen. Dies führt sehr wahrscheinlich zu undefiniertem Verhalten, daher empfehle ich es nicht.

    
Caleth 20.12.2017 15:24
quelle
2

Sie können diesen externen synchronen Code in einem anderen Prozess ausführen und diesen gesamten Prozess beenden. Auf diese Weise hat die Unterbrechung keinen Einfluss auf Ihren Prozess und führt zu undefiniertem Verhalten.

    
Maxim Egorushkin 22.12.2017 17:10
quelle

Tags und Links