2016-07-18 1 views
1

Я хотел бы реализовать для реализаций Потребительского Продюсера. Я еще не реализовал потребитель, потому что у меня проблема с Продюсером. Целью является загрузка некоторых файлов в Интернете. Нити запускаются внутри метода пользовательского объекта. Потоки - это объекты подклассификации 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() 

Проблема заключается в том, что запускается поток обычно все пять из них, они выполняют то, что в методе выполнения, но не останавливайтесь, поэтому пока не выполняется. Я новичок в потоковом и параллельном программировании, поэтому, пожалуйста, будьте осторожны :)

Цель состоит в том, чтобы иметь потребительскую нить, занимающуюся частью кода, вместо того, чтобы иметь это в то время как в «main»: часть код

ответ

1

Ваши потоки никогда не заканчиваются, так как они имеют метод run() с бесконечным циклом. В вашем download() методе вы join() для этих потоков:

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

и поэтому программа блокируется. Просто удалите соединения, поскольку, кажется, вы имели в виду, что эти потоки сохраняются в течение всей жизни программы.

+0

Благодарим вас за быстрый ответ. Задание завершения потоков выполняется по очереди с queue.join() и queue.task_done() правильно? – Apostolos

+0

Нет, нити никогда не заканчиваются во время жизни программы с вашей текущей реализацией. Они позволяют завершить программу python, поскольку они являются демонами. Когда 'queue' заканчивается, они блокируются в' page = self.queue.get() '. У вас есть это право с 'queue.task_done()', и вы можете 'queue.join()', что должно ждать, когда все элементы очереди будут получены и обработаны. –

+0

Есть ли способ покончить с потоками, когда загрузка возвращается с текущей реализацией? Наверное, не правильно? Есть ли способ заставить их остановиться? Я слышал, что это не самая лучшая практика, чтобы заставить остановить нить правильно? – Apostolos

Смежные вопросы