Найти - Пользователи
Полная версия: Помогите понять многопоточность.
Начало » Python для новичков » Помогите понять многопоточность.
1 2 3
Ed
Чем мой не угодил? Давайте разбираться. Попытайтесь понять как работает мой код, задавайте вопросы. Когда поймете - модифицируйте ту часть, которая собственно делает работу, чтобы она делала то, что вам нужно. Вот такой план. Вуаля.
Soteric
Ваши потоки работают в бесконечном цикле и не знают когда им завершить работу. Когда очередь пустеет, то они “повисают” здесь
host = self.queue.get()
в ожидании новых задач. Вы можете в конце класть в очередь некие объекты-маркеры, получение которых будет для потока сигналом к остановке.
# Класс объекта-маркера
class JobDone(object):
pass
...
# После того как в очередь положили все host, создаем
# и кладем число объектов-маркеров по числу потоков
for i in range(60):
queue.put(JobDone())
...
# В коде потока проверяем что мы достали из очереди и если
# это объект-маркер завершения работы, то выходим из цикла
while True:
#grabs host from queue
host = self.queue.get()

if isinstance(host, JobDone):
break
ДОБАВЛЕНО: И забыл еще сказать, что выполнение задачи должно быть обернуто в try-finally. Поскольку если ваш поток совершит ошибку, то он завершится не отчитавшись о выполнении задачи. Это значит, что если в вашем коде вы сделаете queue.join(), которое приостановит выполнение основного потока до выполнения всех задач, то никогда не сможете выйти из этого ожидания. Поскольку поток задачу на обработку взял, но queue.task_done() так и не выполнил.
while True:
try:
#grabs host from queue
host = self.queue.get()

if isinstance(host, JobDone):
break
...
except Exception as e:
# При желании записываем сведения об ошибке в лог
finally:
queue.task_done()
vlados
Спасибо всем за ответы, но ошибка была куда проще, чем вы думали. Ошибка заключается в том, что я поставил неправильную структуру.
Эд, мне было трудно понять ваш код, было много неясностей, я хотел у вас спросить о них, но потом я нашел сайт где нашел этот пример и хорошее описание.
Было так:
def main():

#spawn a pool of threads, and pass them queue instance
for i in range(60):
t = ThreadUrl(queue)
t.setDaemon(True)
t.start()

#populate queue with data
for host in hosts:
queue.put(host)

#wait on the queue until everything has been processed
queue.join()
А надо так:
def main():

#spawn a pool of threads, and pass them queue instance
for i in range(60):
t = ThreadUrl(queue)
t.setDaemon(True)
t.start()

#populate queue with data
for host in hosts:
queue.put(host)

#wait on the queue until everything has been processed
queue.join()
Soteric
Да, пардон. Не обратил внимания, что это демонические потоки, которые бесконечно работать не будут :)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB