Python:类似于“map”的东西,在线程上工作
我确信在标准图书馆里有类似的东西,但似乎我错了 我有一堆URL,我想同时Python:类似于“map”的东西,在线程上工作,python,multithreading,parallel-processing,map-function,Python,Multithreading,Parallel Processing,Map Function,我确信在标准图书馆里有类似的东西,但似乎我错了 我有一堆URL,我想同时urlopen。我想要像内置的map函数一样的东西,除了工作是由一堆线程并行完成的 有一个好的模块可以做到这一点吗?Python模块队列可能会帮助您。使用一个使用Queue.put()的线程将所有URL推送到队列中,工作线程只需get()逐个推送URL即可 我会将其封装在一个函数中(未测试): 中有一个map方法。这需要多个过程 如果多个进程不是你的盘,你可以使用哪个进程使用线程 import urllib import m
urlopen
。我想要像内置的map
函数一样的东西,除了工作是由一堆线程并行完成的
有一个好的模块可以做到这一点吗?Python模块
队列
可能会帮助您。使用一个使用Queue.put()
的线程将所有URL推送到队列中,工作线程只需get()
逐个推送URL即可
我会将其封装在一个函数中(未测试):
中有一个
map
方法。这需要多个过程
如果多个进程不是你的盘,你可以使用哪个进程使用线程
import urllib
import multiprocessing.dummy
p = multiprocessing.dummy.Pool(5)
def f(post):
return urllib.urlopen('http://stackoverflow.com/questions/%u' % post)
print p.map(f, range(3329361, 3329361 + 5))
有人建议我为此使用
futures
软件包。我试过了,它似乎起作用了
下面是一个例子:
"Download many URLs in parallel."
import functools
import urllib.request
import futures
URLS = ['http://www.foxnews.com/',
'http://www.cnn.com/',
'http://europe.wsj.com/',
'http://www.bbc.co.uk/',
'http://some-made-up-domain.com/']
def load_url(url, timeout):
return urllib.request.urlopen(url, timeout=timeout).read()
with futures.ThreadPoolExecutor(50) as executor:
future_list = executor.run_to_futures(
[functools.partial(load_url, url, 30) for url in URLS])
以下是我对线程映射的实现:
from threading import Thread
from queue import Queue
def thread_map(f, iterable, pool=None):
"""
Just like [f(x) for x in iterable] but each f(x) in a separate thread.
:param f: f
:param iterable: iterable
:param pool: thread pool, infinite by default
:return: list if results
"""
res = {}
if pool is None:
def target(arg, num):
try:
res[num] = f(arg)
except:
res[num] = sys.exc_info()
threads = [Thread(target=target, args=[arg, i]) for i, arg in enumerate(iterable)]
else:
class WorkerThread(Thread):
def run(self):
while True:
try:
num, arg = queue.get(block=False)
try:
res[num] = f(arg)
except:
res[num] = sys.exc_info()
except Empty:
break
queue = Queue()
for i, arg in enumerate(iterable):
queue.put((i, arg))
threads = [WorkerThread() for _ in range(pool)]
[t.start() for t in threads]
[t.join() for t in threads]
return [res[i] for i in range(len(res))]
您的意思是希望map启动线程(如pillmuncher的答案,map(urlopen,url)),还是手动启动urlopening线程,并希望map之类的东西在每个线程的执行结果可用时对其进行操作?streams.fastmap()来自Pyxtension:github.com/asuiu/Pyxtension正是这样做的-多线程映射。这很好,但如果从线程运行,它将无法在python2.6上工作,因为这个bug:在python2.79中工作得很好-目前是最新版本的2x,而且也非常好!令人惊叹的。值得注意的是,它下面实际上是multiprocessing.pool import ThreadPool的
,您需要在第二行导入Empty
。
from threading import Thread
from queue import Queue
def thread_map(f, iterable, pool=None):
"""
Just like [f(x) for x in iterable] but each f(x) in a separate thread.
:param f: f
:param iterable: iterable
:param pool: thread pool, infinite by default
:return: list if results
"""
res = {}
if pool is None:
def target(arg, num):
try:
res[num] = f(arg)
except:
res[num] = sys.exc_info()
threads = [Thread(target=target, args=[arg, i]) for i, arg in enumerate(iterable)]
else:
class WorkerThread(Thread):
def run(self):
while True:
try:
num, arg = queue.get(block=False)
try:
res[num] = f(arg)
except:
res[num] = sys.exc_info()
except Empty:
break
queue = Queue()
for i, arg in enumerate(iterable):
queue.put((i, arg))
threads = [WorkerThread() for _ in range(pool)]
[t.start() for t in threads]
[t.join() for t in threads]
return [res[i] for i in range(len(res))]