Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Immediately kill a running future thread

I'm using

(def f 
   (future 
      (while (not (Thread/interrupted)) 
         (function-to-run))))

(Thread/sleep 100)
(future-cancel f)

to cancel my code after a specified amount of time (100ms).
The problem is, I need to cancel the already running function 'function-to-run' as well, it is important that it really stops executing that function after 100ms.
Can I somehow propagate the interrupted signal to the function?
The function is not third-party, I wrote it myself.

like image 316
gw0 Avatar asked Mar 09 '17 16:03

gw0


People also ask

How do you kill a running thread in Python?

In Python, you simply cannot kill a Thread directly. If you do NOT really need to have a Thread (!), what you can do, instead of using the threading package , is to use the multiprocessing package . Here, to kill a process, you can simply call the method: yourProcess.

How do you stop concurrent futures ThreadPoolExecutor?

You can call the cancel() function on the Future object to cancel the task before it has started running. If your task has already started running, then calling cancel() will have no effect and you must wait for the task to complete.

How do you stop futures in Python?

Call cancel() on the Future to Cancel a Task The Future object has a function called cancel() that will cancel the task if it has not yet started running and is not done.

How do you stop ThreadPool?

There are two ways to shutdown the ThreadPool. They are: Call the close() method. Call terminate() method.


1 Answers

The basic thing to note here is: you cannot safely kill a thread without its own cooperation. Since you are the owner of the function you wish to be able to kill prematurely, it makes sense to allow the function to cooperate and die gracefully and safely.

(defn function-to-run
  []
  (while work-not-done
    (if-not (Thread/interrupted)
      ; ... do your work
      (throw (InterruptedException. "Function interrupted...")))))

(def t (Thread. (fn []
                  (try
                    (while true
                      (function-to-run))
                    (catch InterruptedException e
                      (println (.getMessage e)))))))

To begin the thread

(.start t)

To interrupt it:

(.interrupt t)

Your approach was not sufficient for your use case because the while condition was checked only after control flow returned from function-to-run, but you wanted to stop function-to-run during its execution. The approach here is only different in that the condition is checked more frequently, namely, every time through the loop in function-to-run. Note that instead of throwing an exception from function-to-run, you could also return some value indicating an error, and as long as your loop in the main thread checks for this value, you don't have to involve exceptions at all.

If your function-to-run doesn't feature a loop where you can perform the interrupted check, then it likely is performing some blocking I/O. You may not be able to interrupt this, though many APIs will allow you to specify a timeout on the operation. In the worst case, you can still perform intermittent checks for interrupted in the function around your calls. But the bottom line still applies: you cannot safely forcibly stop execution of code running in the function; it should yield control cooperatively.

Note: My original answer here involved presenting an example in which java's Thread.stop() was used (though strongly discouraged). Based on feedback in the comments, I revised the answer to the one above.

like image 162
Josh Avatar answered Oct 22 '22 14:10

Josh