2015-10-28 3 views
0

У меня есть список Auf URL-адресов, которые должны быть выбраны параллельно, поэтому я использую резьб:Python Threading ждать возвращения

for url in urls: 
    thread = fetch_single(url) 
    threads.append(thread) 
    thread.start() 

for thread in threads: 
    thread.join() 
    # thread.html() is always "None" here: 
    thread.html() 

Мой потоковая рабочий класс:

class fetch_single(threading.Thread): 
    def __init__ (self, url): 
     threading.Thread.__init__(self) 
     self.url = url 
     self.response = None 

    def run(self): 
     self.response = consumer.fetch(self.url) 

    def html(self): 
     return self.response.getData() 

Моя проблема заключается в line self.response = consumer.fetch(self.url). Как я могу добиться, чтобы поток ожидал ответа от подпрограммы/класса?

ответ

0

Это альтернативное решение. Вам нужно будет проверить, является ли каждый отдельный поток «живым» или выполнил свою задачу. Быстрый кусок кода, чтобы показать вам логику бы это:

import threading 
import time 

requests = {} 
urls = ['www.google.se', 'inbox.google.com'] 

class fetch_single(threading.Thread): 
    def __init__ (self, url): 
     threading.Thread.__init__(self) 
     self.url = url 
     self.response = None 

    def html(self): 
     return self.response.getData() 

    def run(self): 
     self.response = consumer.fetch(self.url) 
     requests[self.url] = self.html() 

for url in urls: 
    thread = fetch_single(url) 
    thread.start() 

while len(threading.enumerate()) > 1: 
    time.sleep(1) 

for url in requests: 
    html = requests[url] 

while len(threading.enumerate()) > 1 бы проверить, если все дети-нити были завершены/убиты, но основной поток (сценарий) до сих пор жив. Обычно в этом цикле вы проверяете значение внутри потока или имеете какую-то систему связи с потоками, чтобы проверить, завершена ли обработка.

Но это даст вам лучшую платформу для начала.

Также обратите внимание, что я решил сохранить ваши данные HTML в глобальной переменной с именем requests вместо того, чтобы извлекать ее из потока, потому что это будет операция блокировки. как правило, вы могли бы сделать что-то такое, как:

def check_html(self): 
    if self.respones: 
     return true 

Обратите внимание, что вы хотите заменить while len... с:

for thread in threading.enumerate(): 
    thread.check_html() 

или что-то вдоль этих линий, лучше всего подходит для ваших нужд.

+0

Есть ли более отзывчивый подход без сна и активного ожидания? Что-то вроде прерывания (назад к основному процессу, чтобы проверить, завершены ли все потоки) после прекращения потока? Я хочу использовать его как веб-сервис, и поэтому время отклика имеет решающее значение ... – RoyalKnight

+0

@RoyalKnight Вы можете использовать 'threads.join()', и это должно дождаться завершения всех процессов. Вам просто нужно заменить метод 'while .. sleep', по крайней мере, он должен работать с моей моделью. Но мне нужно будет дважды проверить. – Torxed

+0

Но это то, что я уже реализовал? Я понимаю, что 'thread.join()' должен ждать, пока поток не будет завершен, поэтому результат не должен быть 'None'? – RoyalKnight

0

Проблема была в области consumer. Я должен был впрыснуть consumer в fetch_single класс:

class fetch_single(threading.Thread): 
    def __init__ (self, consumer, url): 
     threading.Thread.__init__(self) 
     self.consumer = consumer 
     self.url = url 
     self.response = None 

    def run(self): 
     self.response = self.consumer.fetch(self.url) 

    def html(self): 
     return self.response.getData()