如何在多线程编程中关闭线程?

6
为了简化我的问题:我正在尝试在Python 2.7中在线程仍在运行时终止它,但我不知道如何做到这一点。 看看这个简单的代码:
import time
import threading

def thread1():
        print "Starting thread 1"
        while True:
                time.sleep(0.5)
                print "Working"

thread1 = threading.Thread(target=thread1, args=())
thread1.start()

time.sleep(2)
print "Killing thread 1"
thread2.stop()
print "Checking if it worked:"
print "Thread is: " + str(thread1.isAlive())

线程1一直在“工作”,我正在尝试在主线程中终止它。有什么好的方法吗?我已经尝试过:

threat1.terminate
threat1.stop
threat1.quit
threat1.end

这一切似乎都指向不可能用简单的代码行来完全阻止它。你有什么建议吗?

使用进程可以通过p.terminate()来终止,但是使用线程并不那么容易。https://dev59.com/wXRC5IYBdhLWcg3wW_pk - brennan
3个回答

11
为了终止一个被控制的 Thread,可以使用线程安全的 threading.Event()
import threading, time

def Thread_Function(running):
    while running.is_set():
        print('running')
        time.sleep(1)

if __name__ == '__main__':
    running = threading.Event()
    running.set()

    thread = threading.Thread(target=Thread_Function, args=(running,))
    thread.start()

    time.sleep(1)
    print('Event running.clear()')
    running.clear()

    print('Wait until Thread is terminating')
    thread.join()
    print("EXIT __main__")

输出:

running  
running  
Event running.clear()  
Wait until Thread is terminating  
EXIT __main__

使用Python 3.4.2进行测试


在线演示:reply.it


1
更好的做法是:将Event的含义从“运行”翻转为“应该停止”,不要进行set操作,只需将其保留在初始未设置状态。然后更改while条件为while not shouldstop.wait(1):并删除time.sleep(1)调用。现在,当主线程调用shouldstop.set()(替换running.clear())时,线程会立即响应,而不需要等待最多一秒钟的time.sleep(1)结束。注意:在Python 2上,这不如可能(因为定时的wait是使用轮询循环实现的,它会进行微小的睡眠),但在Python 3上是零开销的。 - ShadowRanger

4
通常情况下,我会使用某种信号来处理这些情况:
import time
import threading

class thread1(threading.Thread):

    def run(self):
        self.kill = False
        print "Starting thread 1"
        while not self.kill:
                time.sleep(0.5)
                print "Working"

thread_obj = thread1()
thread_obj.start()

time.sleep(2)
print "Killing thread 1"
thread_obj.kill = True
print "Checking if it worked:"
time.sleep(1)
print "Thread is: " + str(thread_obj.isAlive())

编辑

在阅读评论中建议的答案后,我意识到这只是那里所描述的简化版本。无论如何,我希望这会有用。


2

确实如此!

线程不能被销毁、停止、暂停、恢复或中断

(如文档中在链接下方的一段所述。)

让你的线程监听你可能发送的信号,通过队列(最佳)、共享变量(较差)或任何其他方式。要小心,不要让它们运行未经检查的循环,就像你的示例代码一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接