Python线程等待返回

时间:2015-10-28 13:40:23

标签: python

我有一个列表auf URL,必须并行获取,因此我使用线程:

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

我的问题是第self.response = consumer.fetch(self.url)行。如何实现,线程等待子例程/类的响应?

2 个答案:

答案 0 :(得分: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()

或其他最适合您需求的东西。

答案 1 :(得分: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()