python进程池卡住_Python,调用进程池而不阻塞事件循环

If I run the following code:

import asyncio

import time

import concurrent.futures

def cpu_bound(mul):

for i in range(mul*10**8):

i+=1

print('result = ', i)

return i

async def say_after(delay, what):

print('sleeping async...')

await asyncio.sleep(delay)

print(what)

# The run_in_pool function must not block the event loop

async def run_in_pool():

with concurrent.futures.ProcessPoolExecutor() as executor:

result = executor.map(cpu_bound, [1, 1, 1])

async def main():

task1 = asyncio.create_task(say_after(0.1, 'hello'))

task2 = asyncio.create_task(run_in_pool())

task3 = asyncio.create_task(say_after(0.1, 'world'))

print(f"started at {time.strftime('%X')}")

await task1

await task2

await task3

print(f"finished at {time.strftime('%X')}")

if __name__ == '__main__':

asyncio.run(main())

The output is:

started at 18:19:28

sleeping async...

result = 100000000

result = 100000000

result = 100000000

sleeping async...

hello

world

finished at 18:19:34

This shows that the event loop blocks until the cpu bound jobs (task2) finish and it continues afterwards with the task3.

If I run only one cpu bound job (the run_in_pool is the following one):

async def run_in_pool():

loop = asyncio.get_running_loop()

with concurrent.futures.ProcessPoolExecutor() as executor:

result = await loop.run_in_executor(executor, cpu_bound, 1)

Then it seems that the event loop doesn't block since the output is:

started at 18:16:23

sleeping async...

sleeping async...

hello

world

result = 100000000

finished at 18:16:28

How can I run many cpu bound jobs (in task2) in a process pool without blocking the event loop?

解决方案

As you discovered, you need to use asyncio's own run_in_executor to wait for submitted tasks to finish without blocking the event loop. Asyncio doesn't provide the equivalent of map, but it's not hard to emulate it:

async def run_in_pool():

with concurrent.futures.ProcessPoolExecutor() as executor:

futures = [loop.run_in_executor(executor, cpu_bound, i)

for i in (1, 1, 1)]

result = await asyncio.gather(*futures)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 是的,我可以用文告诉你如何使用 Python 进程。 首先,你需要导入 Python 标准库的 `multiprocessing` 模块。然后,你可以使用 `multiprocessing.Pool` 类来创建一个进程。你可以通过指定要创建的进程数来自定义进程。例如,下面的代码创建一个包含 4 个进程进程: ``` import multiprocessing pool = multiprocessing.Pool(4) ``` 你可以使用 `apply()` 或 `apply_async()` 方法进程添加任务。下面是一个使用 `apply()` 方法添加任务的例子: ``` def square(x): return x * x result = pool.apply(square, (10,)) print(result) # prints 100 ``` 你也可以使用 `map()` 或 `map_async()` 方法进程添加多个任务。下面是一个使用 `map()` 方法添加多个任务的例子: ``` def square(x): return x * x results = pool.map(square, range(10)) print(results) # prints [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] ``` 最后,你可以使用 `close()` 和 `join()` 方法关闭进程并等待所有任务完成。例如: ``` pool.close() pool.join() ``` 我希望这些信息能帮到你。如果你还有其他问题,请随时追问。 ### 回答2: 当然可以。Python标准库的`multiprocessing`模块提供了一个用于创建进程的类`Pool`。以下是使用Python编写进程的详细步骤: 首先,我们需要导入`multiprocessing`模块的`Pool`类: ```python import multiprocessing ``` 然后,可以初始化一个进程实例。可以指定进程进程的数量,默认为当前系统的CPU核心数: ```python pool = multiprocessing.Pool() ``` 接下来,我们需要编写一个函数,作为进程每个进程的执行任务。该函数需要接收一个参数,在本例为整数`num`: ```python def square(num): return num * num ``` 然后,我们可以通过使用`apply_async`方法进程提交任务。该方法接受两个参数:第一个参数是需要执行的函数名,第二个参数是需要传递给函数的参数。该方法是非阻塞的,即它立即返回一个`ApplyResult`对象,我们可以通过该对象的`get()`方法获取执行结果: ```python result = pool.apply_async(square, (5,)) print(result.get()) # 输出结果为25 ``` 此外,我们也可以使用`map`方法来批量提交任务。该方法接收两个参数:第一个参数是需要执行的函数名,第二个参数是一个可迭代对象,包含了需要传递给函数的参数。`map`方法返回一个可迭代对象,其包含了每个任务的执行结果: ```python results = pool.map(square, [1, 2, 3, 4, 5]) print(results) # 输出结果为[1, 4, 9, 16, 25] ``` 最后,我们可以调用`close`方法来停止向进程添加新的任务,并调用`join`方法等待所有任务执行完成: ```python pool.close() pool.join() ``` 以上就是使用Python编写一个简单的进程的详细步骤。进程可以有效地利用多核CPU,并行执行任务,提高程序的性能。 ### 回答3: 当然可以。Python提供了`multiprocessing`模块,用于处理进程相关的操作,如进程的创建、管理和通信等。下面我将详细介绍如何用Python编写一个进程。 首先,导入`multiprocessing`模块,实例化一个进程对象,可以通过指定`processes`参数来设置进程进程的数量。 ```python import multiprocessing pool = multiprocessing.Pool(processes=4) # 创建一个拥有4个进程进程 ``` 接下来,定义一个需要在多个进程执行的函数,例如`do_work`。 ```python def do_work(data): # 定义需要在多个进程执行的任务 # ... return result ``` 然后,可以使用进程的`apply_async`方法来异步地向进程提交任务。 ```python result = pool.apply_async(do_work, (data,)) # 向进程提交一个任务 ``` 这里的`do_work`是需要执行的函数,`data`是传递给函数的参数。可以通过元组的形式传递多个参数。`apply_async`方法返回一个`AsyncResult`对象,可以使用其`get`方法来获取任务的执行结果。 ```python result.get() # 获取任务的执行结果 ``` 除了`apply_async`方法进程还提供了`map`和`map_async`方法用于批量提交任务,并将结果以列表的形式返回。 最后,当所有任务完成后,需要调用进程的`close`方法和`join`方法来回收进程。 ```python pool.close() # 关闭进程,不再接受新的任务 pool.join() # 等待所有任务完成 ``` 这样就完成了进程的详细使用了。进程可以提高程序的并发执行效率,适用于需要大量并行处理的任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值