我的python脚本创建了很多线程,它们都是守护程序线程,我发现我收到一条错误,说“内存不足”。
如何在脚本/应用程序运行时终止守护程序线程?
我理解守护程序线程的概念,它们在我的进程(脚本或应用程序)关闭/完成时会自行销毁。但我想杀死我的一些守护程序线程,同时我的脚本仍在运行以避免“内存不足”错误。
如果队列中没有其他任务,我的线程会自杀吗?
class ParsePageThread(threading.Thread):
THREAD_NUM = 0
def __init__(self, _queue):
threading.Thread.__init__(self)
self.queue = _queue
def run(self):
while(True):
try:
url = self.queue.get()
except Queue.Empty,e:
return # WILL this kill the thread?
finally:
self.queue.task_done()
答案 0 :(得分:3)
我会先回答你的第二个问题,因为它更容易。是的,从run方法返回确实会停止该线程。详细解释是threading: Thread Objects doc。
要在自然完成之前停止正在运行的线程,您必须获得更多创意。线程对象上没有直接的kill方法。您需要做的是使用共享变量来定义线程的状态。
alive = True
class MyThread(threading.Thread):
def run():
while(alive):
#do work here
在其他一些代码中,当您检测到停止该线程的条件时,另一个线程只将alive设置为False:
alive = False
这是一个简单的例子,我将留给你扩展到多个线程。
此示例有效,因为由于Global Interpreter Lock,在python中读取和设置布尔变量是 atomic 操作。 Here是低级python线程的优秀教程。你应该坚持使用Queue对象,因为这正是它的用途。
如果您执行的操作不仅仅是从多个线程中读取和设置简单变量,则应使用Locks或Reentrant Locks,具体取决于您的设计和需求。即使像没有锁定的比较和交换这样简单的事情也会导致程序中很难调试的问题。
python多线程的另一条建议是永远不要在解释器线程中做任何重要的工作。它应该设置并启动所有其他线程,然后睡眠或等待condition object,直到程序退出。原因是没有其他python线程可以接收操作系统signals。这意味着没有其他线程可以处理Ctrl+C
又名KeyboardInterrupt
例外。让主线程处理KeyboardInterrupt
异常然后将所有活动变量设置为False是一个很好的做法,这样您就可以快速退出程序。这在开发过程中尤其有用,因此当您犯错时不必经常杀人。