Python 线程脚本在结束后停止而不关闭
希望这只是我做错的小事情,因为这是我第一次使用队列的线程脚本。基本上,跑完之后,它会停下来,坐在那里,但不会退出Python 线程脚本在结束后停止而不关闭,python,multithreading,queue,Python,Multithreading,Queue,希望这只是我做错的小事情,因为这是我第一次使用队列的线程脚本。基本上,跑完之后,它会停下来,坐在那里,但不会退出 import threading import Queue class Words(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.queue = Queue.Queue() def word(self):
import threading
import Queue
class Words(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.queue = Queue.Queue()
def word(self):
read = open('words.txt')
for word in read:
word = word.replace("\n","")
self.queue.put(word)
read.close()
for i in range(5):
t = self.run()
t.setDaemon(True)
t.start()
self.queue.join()
def run(self):
while True:
word = self.queue.get()
print word
self.queue.task_done()
if __name__ == '__main__':
Word = Words()
Word.word()
在我看来,当你真的需要一个简单的解决方案时,你把线程的许多不同方面都混在了一起。据我所知,范围(5):中I的
循环永远不会通过第一次迭代,因为您运行线程,它会陷入无限循环中
我会这样做:
import threading
import Queue
class Worker(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
while True:
# try to dequeue a word from the queue
try:
word = self.queue.get_nowait()
# if there's nothing in the queue, break because we're done
except Queue.Empty:
break
# if the 'try' was successful at getting a word, print it
print word
def fill_queue(queue):
read = open('words.txt')
for word in read:
word = word.replace("\n", "")
queue.put(word)
read.close()
if __name__ == "__main__":
# create empty queue
queue = Queue.Queue()
# fill the queue with work
fill_queue(queue)
# create 5 worker threads
threads = []
for i in range(5):
threads.append(Worker(queue))
# start threads
for thread in threads:
thread.start()
# join threads once they finish
for thread in threads:
thread.join()
您在代码中以几种方式错误地使用了线程:
首先,代码似乎建立在一个错误的假设之上,即您拥有的Thread
子类对象可以生成完成工作所需的所有线程。相反,表示每个线程
对象最多只能调用一次start
。对于word
方法,这是self
参考
但是,调用self.start()
是没有用的,因为这样会产生一个线程来使用队列,而线程化不会带来任何好处。由于word
无论如何都必须构造Words
的新实例才能启动多个线程,并且队列对象将需要由多个Words
实例访问,因此将这两个实例与Words
对象分开是很有用的。例如,word
可以是Words
对象之外的函数,其开头类似:
def word():
queue = Queue.Queue()
read = open('words.txt')
for word in read:
word = word.replace("\n","")
self.put(word)
read.close()
#...
这也意味着Words
必须将队列对象作为参数,以便多个实例共享同一队列:
class Words(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
其次,线程函数(run
)是一个无限循环,因此线程永远不会终止。由于您仅在将所有项目添加到队列后才运行队列使用者线程,因此在队列为空时终止线程应该不会有问题,如下所示:
def run(self):
while True:
try:
word = self.queue.get(False)
except Queue.Empty:
break
print word
self.queue.task_done()
在这里使用异常是很有用的,因为否则队列可能会清空,然后线程可能会尝试从中获取,它将永远等待添加项
第三,在for循环中调用self.run()
,它将控制权传递给run
方法,然后该方法处理整个队列,并在方法更改为终止后返回None
。以下行将抛出异常,因为t
将被分配值None
。由于您希望生成其他线程来执行此工作,因此应该执行t=Word(queue)
以获取新的Word线程,然后执行t.start()
以启动。因此,当代码组合在一起时,应该
class Words(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
while True:
try:
word = self.queue.get(False)
except Queue.Empty:
break
print word
self.queue.task_done()
def word():
queue = Queue.Queue()
read = open('words.txt')
for word in read:
word = word.replace("\n","")
self.put(word)
read.close()
for i in range(5):
t = Word()
t.setDaemon(True)
t.start()
queue.join()
if __name__=='__main__':
word()
如果您想阅读Python中的一些线程代码示例,下面的方法可能会教您一些关于这个主题的基础知识。其中一些是演示,另一些是程序:
在这段代码中,您试图启动5个线程来处理队列中的所有项目?