在单个发电机上消耗/迭代的多个过程(分隔和征服)



我有一个python发电机,可以返回很多项目,例如:

import itertools
def generate_random_strings():
    chars = "ABCDEFGH"
    for item in itertools.product(chars, repeat=10):
        yield "".join(item)

i然后对此进行迭代并执行各种任务,问题是我只使用一个线程/过程:

my_strings = generate_random_strings()
for string in my_strings:
    # do something with string...
    print(string)

这很好,我得到了所有的弦,但是很慢。我想利用Python多处理的力量来"分裂和征服"此循环。但是,当然,我希望每个字符串仅处理一次。虽然我找到了有关多处理的大量文档,但我试图以最少的代码找到最简单的解决方案。我假设每个线程都应每次都要拿大量物品并处理它们,然后再回来并获得另一个大块等...

非常感谢,

使用最少代码的最简单解决方案?多处理上下文管理器。

我认为您可以将"用字符串做某事"放入称为" do_something"

的函数
from multiprocessing import Pool as ProcessPool
number_of_processes = 4
with ProcessPool(number_of_processes) as pool:
    pool.map(do_something, my_strings)

如果您想再次获得" do_something"的结果,请轻松!

with ProcessPool(number_of_processes) as pool:
    results = pool.map(do_something, my_strings)

您会将它们放在列表中。

Multiprocessing.dummy是过程池的句法包装器,可让您使用多处理语法。如果您想要线程而不是进程,请执行此操作:

from multiprocessing.dummy import Pool as ThreadPool

您可以使用multiprocessing

import multiprocessing
def string_fun(string):
    # do something with string...
    print(string)
my_strings = generate_random_strings()
num_of_threads = 7
pool = multiprocessing.Pool(num_of_threads)
pool.map(string_fun, my_strings)

假设您使用的是Python的最后版本,则可能需要阅读有关Asyncio模块的内容。由于GIL锁定,多线程不容易实现:"在Cpython中,全局解释器锁定或GIL是一个静音,可以保护对Python对象的访问,防止多个线程一次执行Python bytecodes。主要是因为Cpython的内存管理不是线程安全。"

因此,您可以在多处理上交换,或者如上所述,查看Asycio模块。
异步 - 异步I/O> https://docs.python.org/3/library/asyncio.html

我将尽快将此答案与一些代码集成。
希望它有帮助,
hele

正如@hele提到的,asyncio是最好的,这是一个示例

代码

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# python 3.7.2
from asyncio import ensure_future, gather, run
import random
alphabet = 'ABCDEFGH'
size = 1000

async def generate():
    tasks = list()
    result = None
    for el in range(1, size):
        task = ensure_future(generate_one())
        tasks.append(task)
        result = await gather(*tasks)
    return list(set(result))

async def generate_one():
    return ''.join(random.choice(alphabet) for i in range(8))

if __name__ == '__main__':
    my_strings = run(generate())
    print(my_strings)

输出

['CHABCGDD', 'ACBGAFEB', ...

当然,您需要改进Generate_one,此变体非常慢。

您可以在此处看到源代码。

相关内容

  • 没有找到相关文章

最新更新