我有一个返回大量项目的python生成器,例如:
import itertools
def generate_random_strings():
chars = "ABCDEFGH"
for item in itertools.product(chars, repeat=10):
yield "".join(item)
然后我对此进行迭代并执行各种任务,问题在于我为此只使用了一个线程/进程:
my_strings = generate_random_strings()
for string in my_strings:
# do something with string...
print(string)
这很好用,我得到了所有的琴弦,但是很慢。我想利用Python多处理的功能来“分而治之”这个for循环。但是,当然,我希望每个字符串仅处理一次。虽然我找到了许多有关多处理的文档,但我正在尝试以最少的代码找到最简单的解决方案。 我假设每个线程每次都应该占用大量的项目并在返回并获得另一个较大的项目之前对其进行处理...
非常感谢,
答案 0 :(得分:0)
使用最少的代码最简单的解决方案?多处理上下文管理器。
我假设您可以将“用字符串做某事”放入名为“ 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
答案 1 :(得分:0)
您可以使用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)
答案 2 :(得分:0)
假设您使用的是最新版本的Python,则可能需要阅读有关asyncio模块的内容。多线程处理由于GIL锁而难以实现:“在CPython中,全局解释器锁或GIL是互斥体,用于保护对Python对象的访问,从而防止多个线程一次执行Python字节码。此锁是必需的主要是因为CPython的内存管理不是线程安全的。”
因此,您可以交换进行多处理,或者如上所述查看asycio模块。
异步—异步I / O> https://docs.python.org/3/library/asyncio.html
我会尽快将此答案与一些代码集成。
希望能帮上忙,
Hele
答案 3 :(得分:0)
正如@Hele所提到的,asyncio是最好的,这是一个示例
代码
_>>_ : {A : Set} {B : Set} (m₁ : (IO B)) (m₂ : (IO A)) → IO A
_>>_ a b = (♯ a) IO.>> (♯ b)
输出
#!/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)
当然,您需要改进generate_one,这种变体非常慢。