Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从生产者-消费者队列中的另一个类执行线程_Python_Multithreading_Queue_Producer Consumer - Fatal编程技术网

Python 从生产者-消费者队列中的另一个类执行线程

Python 从生产者-消费者队列中的另一个类执行线程,python,multithreading,queue,producer-consumer,Python,Multithreading,Queue,Producer Consumer,我想实现一个消费者-生产者实现。我还没有实现consumer,因为我与生产商有问题。目的是在互联网上下载一些文件。线程在自定义对象的方法内启动。线程是threading.Thread子类化的对象。这是密码 downloader_thread.py from threading import Thread import time class Downloader(Thread): def __init__(self, queue, out_queue): super(

我想实现一个消费者-生产者实现。我还没有实现consumer,因为我与生产商有问题。目的是在互联网上下载一些文件。线程在自定义对象的方法内启动。线程是threading.Thread子类化的对象。这是密码

downloader_thread.py

from threading import Thread

import time


class Downloader(Thread):
    def __init__(self, queue, out_queue):
        super(Downloader, self).__init__()
        self.queue = queue
        self.out_queue = out_queue

    def run(self):
        while True:
            page = self.queue.get()
            if page:
                print "Simulating download"
                print "Downloading page ", page
                time.sleep(3)
                self.out_queue.put(page)

            self.queue.task_done()
main_class.py

from Queue import Queue

from downloader_thread import Downloader


class Main(object):
    def __init__(self):
        self.queue = Queue(0)
        self.out_queue = Queue(0)
        self.threads = []
        self.max_threads = 5

    def download(self):
        page = 1
        for i in range(self.max_threads):
            download_thread = Downloader(self.queue, self.out_queue)
            download_thread.setDaemon(True)
            download_thread.start()
            self.threads.append(download_thread)

        while page < 100:
            self.queue.put(page)
            page += 1

        self.queue.join()

        for thread in self.threads:
            thread.join()


if __name__ == "__main__":

    main = Main()
    main.download()
    while not main.out_queue.empty():
        print main.out_queue.get()
从队列导入队列
从downloader\u线程导入downloader
类主(对象):
定义初始化(自):
self.queue=队列(0)
self.out_queue=队列(0)
self.threads=[]
self.max_线程数=5
def下载(自助):
页码=1
对于范围内的i(self.max_线程):
下载线程=下载程序(self.queue、self.out\u queue)
下载_thread.setDaemon(True)
下载_thread.start()
self.threads.append(下载线程)
页面<100时:
self.queue.put(第页)
页码+=1
self.queue.join()
对于self.threads中的线程:
thread.join()
如果名称=“\uuuuu main\uuuuuuuu”:
main=main()
main.download()
而不是main.out\u queue.empty():
打印main.out_queue.get()
问题是线程通常都是启动的,它们执行run方法中的操作,但不会停止,所以while永远不会执行。我对线程和并发编程有点陌生,所以请温柔一点:)


关键是让使用者线程处理代码的while部分,而不是在“main”中使用while:代码的一部分

您的线程永远不会终止,因为它们有一个无限循环的
run()
方法。在
download()
方法中,您可以将这些线程:

        for thread in self.threads:
            thread.join()

所以程序被阻止了。只需删除连接,因为您似乎希望这些线程在程序的生命周期内保持不变。

感谢您的快速响应。终止线程的工作由队列负责,队列包含queue.join()和queue.task_done()正确吗?否,在程序的生命周期内,线程在当前实现中不会终止。它们确实允许终止python程序,因为它们是守护线程。当
queue
用完时,它们被阻塞在
page=self.queue.get()
中。您确实可以使用
队列.task_done()
,您可以使用
队列.join()
,等待获取和处理队列中的所有项目。当下载返回当前实现时,是否有方法结束线程?我猜不对吧?有没有办法迫使他们停止?我听说强制正确停止线程不是最佳做法?例如,如果确实需要停止线程,请让它们在某些条件下循环,而不是在“True:”时循环。这还要求您不要在
get()
中无限期地阻塞。添加一个超时,捕获并忽略
队列。清空
。好的……总而言之……当可调用线程退出(运行或目标)时,线程被破坏。开发人员有责任添加关于如何终止线程的逻辑。谢谢。