1

Basically, I have some threads that MAY block on I/O but has to be stopped in some cases. The entire software architecture is already designed like that, so switching to multi-processing can be painful. Therefore, I searched web and found using thread_ref._Thread__stop() seems to be the only way that can guarantee to stop a blocked thread.

The problem now is, though that thread is stopped, it is NOT removed from threading.enumerate(). If I call isAlive() on its reference, it returns False. I tried if a thread's run() method returns normally, that thread should be removed from that list.

This is bad, because if threading still has a reference to that Thread object, its resources will not be collected, theoretically, and may eventually cause memory leak.

What should I do to make sure things are cleaned up after I do _Thread__stop on a thread?

martineau
  • 99,260
  • 22
  • 139
  • 249
bfrguci
  • 127
  • 1
  • 8
  • 2
    There is no supported way to stop a thread in Python. In particular, the `_stop()` method does nothing of the sort, and was made private precisely because it's an implementation detail of no conceivable use outside of `Thread`'s internal bookkeeping (it does _not_ stop the thread - it's used by `Thread` internals when a thread exits on its own). More here: http://stackoverflow.com/questions/18018033/how-to-stop-a-looping-thread-in-python – Tim Peters Aug 07 '16 at 04:59

1 Answers1

2

Expanding on my comment, nobody ever believes this ;-) , so here's some code that shows it (Python 2 only):

from time import sleep
import threading

def f():
    while True:
        print("running")
        sleep(1)

t = threading.Thread(target=f)
print("starting thread")
t.start()
sleep(.5)
print("'stopping' thread")
t._Thread__stop()
sleep(2)
print("huh! thread is still running")
sleep(10)

And the output:

starting thread
running
'stopping' thread
running
running
huh! thread is still running
running
running
running
running
running
running
running
running
running
running

_Thread__stop is useless for stopping the thread (there's nothing else in threading that can force a thread to stop either).

What calling it does do is put threading's internals into a confused state. In this case, because ._stop() was called some other parts of threading erroneously believe the thread has stopped, so Python merrily exits after the final sleep despite that the non-daemon thread t is still running.

But that's not a bug: you use private, undocumented methods (like ._stop()) at your own risk.

Tim Peters
  • 55,793
  • 10
  • 105
  • 118