将python线程结果合并为一个列表

ree*_*106 2 python concurrency multithreading http urllib2

我正在尝试修改此处显示的解决方案:用Python发送100,000个HTTP请求的最快方法是什么?除了不是检查标头状态而是创建一个返回字典的API请求外,我希望所有这些API请求的最终结果都是所有字典的列表。

这是我的代码-考虑到api_calls是一个列表,每个列表都为json请求打开...

from threading import Thread
from Queue import Queue

concurrent = 200 

def doWork():
    while True:
        url = q.get()
        result = makeRequest(url[0])
        doSomethingWithResult(result, url)
        q.task_done()

def makeRequest(ourl):
    try:
        api_call = urlopen(ourl).read()
        result = json.loads(api_call)
        return result, ourl
    except:
        return "error", ourl

def doSomethingWithResult(result, url):
  print(url,result)

q = Queue(concurrent * 2)
for i in range(concurrent):
    t = Thread(target=doWork)
    t.daemon = True
    t.start()
try:
    for url in api_calls:
        q.put(url)
    q.join()
except KeyboardInterrupt:
    sys.exit(1)
Run Code Online (Sandbox Code Playgroud)

像链接的示例一样,当前可以成功在每行上打印url和结果。我想做的是将(url,result)添加到每个线程的列表中,然后最后将它们加入一个主列表中。我不知道如何拥有此主列表并在最后加入结果。有人可以帮我在doSomethingWithResult中进行修改吗?如果我正在做一个大循环,我将只有一个空列表,并将每个API请求后的结果附加到列表中,但是由于我正在使用线程,因此我不知道如何模仿这一点。

我希望一个常见的响应是使用https://en.wikipedia.org/wiki/Asynchronous_I/O,如果这是建议,那么我将不胜感激有人实际上提供了一个示例,该示例可以完成我所拥有的代码上面链接。

tde*_*ney 5

使用ThreadPool代替。它为您完成了繁重的工作。这是一个获取一些URL的工作示例。

import multiprocessing.pool
concurrent = 200 

def makeRequest(ourl):
    try:
        api_call = urlopen(ourl).read()
        result = json.loads(api_call)
        return "success", ourl
    except:
        return "error", ourl

def main():
    api_calls = [
        'http:http://jsonplaceholder.typicode.com/posts/{}'.format(i)
        for i in range(1,5)]

    # a thread pool that implements the process pool API.
    pool = multiprocessing.pool.ThreadPool(processes=concurrent)
    return_list = pool.map(makeRequest, api_calls, chunksize=1)
    pool.close()
    for status, data in return_list:
        print(data)

main()
Run Code Online (Sandbox Code Playgroud)