Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Properly Kill/Exit Futures Thread?

I was previously using the threading.Thread module. Now I'm using concurrent.futures -> ThreadPoolExecutor. Previously, I was using the following code to exit/kill/finish a thread:

def terminate_thread(thread):
    """Terminates a python thread from another thread.

    :param thread: a threading.Thread instance
    """
    if not thread.isAlive():
        return

    exc = ctypes.py_object(SystemExit)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
        ctypes.c_long(thread.ident), exc)
    if res == 0:
        raise ValueError("nonexistent thread id")
    elif res > 1:
        # """if it returns a number greater than one, you're in trouble,
        # and you should call it again with exc=NULL to revert the effect"""
        ctypes.pythonapi.PyThreadState_SetAsyncExc(thread.ident, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")

This doesn't appear to be working with futures interface. What's the best practice here? Just return? My threads are controlling Selenium instances. I need to make sure that when I kill a thread, the Selenium instance is torn down.

Edit: I had already seen the post that is referenced as duplicate. It's insufficient because when you venture into something like futures, behaviors can be radically different. In the case of the previous threading module, my terminate_thread function is acceptable and not applicable to the criticism of the other q/a. It's not the same as "killing". Please take a look at the code I posted to see that.

I don't want to kill. I want to check if its still alive and gracefully exit the thread in the most proper way. How to do with futures?

like image 482
xendi Avatar asked Oct 03 '18 16:10

xendi


People also ask

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. The cancel() function returns True if the task was canceled, otherwise False if the task could not be canceled.

How do you kill a 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 prevent 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.


1 Answers

If you want to let the threads finish their current work use:

thread_executor.shutdown(wait=True)

If you want to bash the current futures being run on the head and stop all ...future...(heh) futures use:

thread_executor.shutdown(wait=False)
for t in thread_executor._threads:
    terminate_thread(t)

This uses your terminate_thread function to call an exception in the threads in the thread pool executor. Those futures that were disrupted will return with the exception set.

like image 143
SargeATM Avatar answered Oct 09 '22 19:10

SargeATM