开发者

Python: How to terminate a blocking thread [duplicate]

This question already has answers here: Closed 10 years ago.

Possible Duplicate:

Is there any way to kill a Thread in Python?

So this question is a follow up to a solution posted previously. Basically it deals with programatically terminating a thread: http://sebulba.wikispaces.com/recipe+thread2

However it doesnt work... and I was wondering if someone can explain how one could terminate a thread that is blocking? My only guess is the fact that I am not providing the right thread id, but I did some testing and am pretty sure I can just use iden

If it is the thread ID, how can I go about getting the correct Thread ID?

Test Code:

class BlockingTestThread(Thread):

    def __init__(self):
        self._running_flag = False
        Thread.__init__(self, target=self.test_method)

    def test_method(self):
        try:
            while(not self.stopped()):
                self._running_flag = True
                time.sleep(100)
        finally:
                self._running_flag = False


def _async_raise(tid, exctype):
    '''Raises an exception in the threads with id tid'''
    if not inspect.isclass(exctype):
        raise TypeError("Only types can be raised (not instances)")

    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), ctypes.py_object(exctype))
    time.sleep开发者_如何学Go(0.1)



if __name__ == "__main__":
    thread = BlockingTestThread()
    thread.start()

    _async_raise(thread.ident, SystemExit)
    print "Joining thread"
    thread.join()
    print "Done Joining thread"
    #will never get here!


Here is a better way to do it, use the "wait" command on the event, asssuming you want to use sleep.

class BlockingTestThread(Thread):
    def __init__(self):
        self._running_flag = False
        self.stop  = threading.Event()
        Thread.__init__(self, target=self.test_method)

    def test_method(self):
        try:
            while(not self.stop.wait(1)):
                self._running_flag = True
                print 'Start wait'
                self.stop.wait(100)
                print 'Done waiting'
        finally:
                self._running_flag = False

    def terminate(self):
         self.stop.set()  

if __name__ == "__main__":
    thread = BlockingTestThread()
    thread.start()

    time.sleep(2)
    print 'Time sleep 2'
    thread.terminate()
    print "Joining thread"
    thread.join()
    print "Done Joining thread"

Obviously you are going to need to wrap your blocking thread in something that uses the pattern above, but if you can't the other option is to cause your process to throw an exception, in our case we basically kill the underlying connection, which causes an exception, and when that exception happens if the stopped flag is set, we ignore it.


You are right about ident, from the docs, ident variable doesn't map to thread id, it's just a reference-

thread.get_ident()

Return the ‘thread identifier’ of the current thread. This is a nonzero integer. Its value has no direct meaning; it is intended as a magic cookie to be used e.g. to index a dictionary of thread-specific data. Thread identifiers may be recycled when a thread exits and another thread is created.

See http://bytes.com/topic/python/answers/45247-terminating-thread-parent re: killling, not sure if it's exactly what you are looking for unfortunately.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜