3

希望这只是我做错的小事,因为这些是我第一个使用队列的线程脚本。基本上在穿过它之后会停下来坐在那里但不会退出。

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()
4

3 回答 3

2

您在代码中以多种方式错误地使用了线程:

首先,代码似乎建立在错误的假设之上,即您拥有的一个Thread子类对象可以产生完成工作所需的所有线程。相反,Thread文档说“每个对象start最多只能调用一次”。Threadword方法的情况下,这是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将被分配 value None。既然你想产生其他线程来完成这项工作,你应该做t = Word(queue)一个新的词线程然后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()
于 2012-05-15T17:44:46.820 回答
0

It looks to me like you're mixing up a number of different aspects of threads, when you really just need a simple solution. As far as I can tell, the for i in range(5): loop never gets past the first iteration because you run the thread and it gets caught in an infinite loop.

Here's how I would do it:

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()
于 2012-05-15T17:39:33.677 回答
0

如果您想阅读一些 Python 中的线程代码示例,以下食谱可能会教您一些有关该主题的基础知识。其中一些是演示,另一些是程序:

于 2012-05-15T18:55:15.053 回答