What is a safe way to stop a running thread?

32,118

Solution 1

Well from you question and subsequent comments I can suggest you two options, with some additional "warnings":

  1. If your thread loops executing something on each iteration, you can set a volatile boolean flag such that it exits after finishing the current iteration (pseudocode because I'm not familiar with python):

    while shouldExit = false
        // do stuff
    

    Then just set the flag to true when you want the thread to stop and it will stop the next time it checks the condition.

  2. If you cannot wait for the iteration to finish and need to stop it immediately, you could go for Thread.Abort, but make absolutely sure that there is no way you can leave open file handles, sockets, locks or anything else like this in an inconsistent state.

Solution 2

What is a safe way to stop a running thread?

Put the thread in its own process. When you want it to stop, kill the process.

That is the only safe way to kill a thread. Aborting a thread can severely destabilize a process and lose user data. There's no way to avoid the "lose user data" scenario if you really, truly need to be able to kill a thread that could be doing anything. The only way to avoid destabilizing the process that is calling for the abort is to make them different processes entirely.

Share:
32,118
aplavin
Author by

aplavin

Researcher at Russian Space Research Institute

Updated on July 13, 2022

Comments

  • aplavin
    aplavin almost 2 years

    I have a thread which contains execution of an IronPython script. For some reason I may need to stop this thread at any time, including script execution. How to achieve this? The first idea is Thread.Abort(), but it's known to be evil...

  • aplavin
    aplavin over 12 years
    The first solution is obvious, but it's not for my case. I was afraid of using Thread.Abort(), because everywhere people write something like "NEVER USE IT!!!"))). But now I use it in the program - ho handles may stay opened.
  • Tudor
    Tudor over 12 years
    It is true that most of the time it's bad, but specifically because people tend to use threads for I/O or other things like this that will be left in an inconsistent state if the thread is killed. If you are not using the thread for anything like this then it's perfectly safe.
  • aplavin
    aplavin over 12 years
    And is it guaranteed, that thread with code like this try { // do work - no try/catches here } catch(ThreadAbortException) { // log exit } will be stopped after calling Abort() on it?
  • Tudor
    Tudor over 12 years
    Unless you are blocked in some I/O inside the try, it should work properly.
  • aplavin
    aplavin over 12 years
    In my case there is no way for the thread code to destabilize the whole process. But for common knowledge - by creating different processes you mean having two projects that are compiled to different assemblies and one of them runs another? Or what?
  • Eric Lippert
    Eric Lippert over 12 years
    @chersanya: You seem awfully sure of yourself. You're running a script; how do you know that the author of the script has not put code in there that will destabilize the process or lose user data when interrupted?
  • Eric Lippert
    Eric Lippert over 12 years
    @chersanya: Absolutely not. That is in no way guaranteed. In particular, if you have hostile code running in the thread you are attempting to abort then you have already lost; hostile code can ignore a thread abort. Aborting a thread should be thought of as a strongly worded suggestion to the thread that it go away; a thread that is hostile to that intent can ignore it at its whim if it is cleverly written.
  • Eric Lippert
    Eric Lippert over 12 years
    @Tudor: To expand on your excellent point: you know what's worse than leaving a file handle open? Closing a file handle when only half the user's data has been buffered out, leaving the document in a broken state such that none of the user's data is recoverable. Similarly with locks; leaving a monitor in the entered state is bad. Exiting a monitor before the code that finishes the protected edit to crucial user data is even worse. People act like aborting threads is bad because it leaves handles allocated, but the actual problem is that it often frees them too early.
  • phoog
    phoog over 12 years
    @chersanya different processes don't necessarily need to be running different assemblies. For example, myprogram.exe could start a new process running myprogram.exe.
  • Kevin Cathcart
    Kevin Cathcart over 12 years
    @Eric, that may be true, but there is also a downside there. Generally speaking you don't want to just go around killing processes. Rather you want send them a signal or message telling them to stop. That is rather important if the process is managing some reasource, so it can restore the resource to a consistant state. For some resources (like file locks, or semaphores) the OS can resotre them (possibly exposing some other resource in an inconsistant state), but not all and the side effects are generally undesireable.
  • Kevin Cathcart
    Kevin Cathcart over 12 years
    To make that fit in with your suggestion, send a message to the new process, which has an "extra" thread that simply looks for the message, does whatever it can to make resources consistant, and then brings down its own process, which inheriently stops the other threads running in it.
  • Eric Lippert
    Eric Lippert over 12 years
    @KevinCathcart: Well, sure. But if you have the ability to control the process politely then surely you also have the ability to control a thread politely. If you can build a control system then by all means do so; I understood the question to be "but what do I do if I cannot control the code but nevertheless I want it to stop, right now?"