【问题标题】:How to correctly pass the generator to the function parameters of ThreadPoolExecutor Executor.map()?如何正确地将生成器传递给 ThreadPoolExecutor Executor.map() 的函数参数?
【发布时间】:2021-06-28 01:28:13
【问题描述】:

在下面的程序中,我有两个问题想问。第一个问题是,当我使用thread poolgenerator 传递给函数时,为什么我需要在调用函数之前遍历generator?第二个问题是如何使用正确的方法将generator传递给ThreadPoolExecutor Executor.map函数。以下程序不调用req函数,遍历path目录下的文件后直接退出

我的最终目录是读取很多图片到base64编码,然后用multiple threads发送HTTP requests得到结果。如果我使用的方法不是最有效的,请给我推荐一些高效优秀的方法,先谢谢了

import json
import requests
import base64
import os
from itertools import repeat
from concurrent.futures.thread import ThreadPoolExecutor



def img_to_base64(img_path):
    for root, dirs, files in os.walk(img_path):
        for pic in files:
            if pic.endswith(('.png', '.jpg', '.jpeg', '.tiff', '.bmp', '.gif')):
                img = os.path.join(root, pic)
                with open(img, 'rb') as f:
                    bs64 = base64.b64encode(f.read()).decode('utf-8')
                yield img,bs64 

def req(host, img, bs64):
    url = f'http://{host}/demo/'
    body = {"requests": [
                    {
                        "resource": {
                            "base64": bs64
                        }
                    }
                ]
            }
    r = requests.post(url, data=json.dumps(body))
    print(img, r)


def run(host,path):
    base64s = img_to_base64(path)
    with ThreadPoolExecutor() as ex:
        ret = list(ex.map(req, repeat(host), base64s))
    return ret

if __name__ == '__main__':
    run('192.168.10.44','/data/')

【问题讨论】:

  • 为什么你认为你需要先遍历生成器?你做了什么改变才能使代码工作?
  • 另外,你为什么要同时标记 3.x 和 2.7? concurrent.futures 至少在 Python 2 中没有提供,至少是内置的。关于你的导入的一个小注释:concurrent.futures.thread 不是一个记录的名称。正确记录的导入将是 from concurrent.futures import ThreadPoolExecutor

标签: python python-3.x python-2.7 python-requests python-multithreading


【解决方案1】:

所以 ThreadPoolExecutor 映射方法需要一个iterable

将生成器对象传递给map 会遍历该可迭代对象。

有一种解决这种行为的方法,但它有点像一个 hacky 方法 - 从列表中调用该生成器方法,这将使您的执行程序接受作为生成器对象,而不是下一个产生的项目

base64s = [img_to_base64(path)]

编辑:

这仅适用于可变迭代器,例如 List(例如,元组,不会得到相同的结果)

这与我们在 python 中模拟指针的方式有关,RealPython 对此特定主题有一个nice explanation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 2016-01-08
    • 2019-11-05
    • 1970-01-01
    • 2014-09-23
    • 1970-01-01
    • 2021-06-29
    相关资源
    最近更新 更多