Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:类似于“map”的东西,在线程上工作_Python_Multithreading_Parallel Processing_Map Function - Fatal编程技术网

Python:类似于“map”的东西,在线程上工作

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

我确信在标准图书馆里有类似的东西,但似乎我错了

我有一堆URL,我想同时
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))]