使用Asyncio创建新的Python进程

时间:2019-05-16 22:28:23

标签: python asynchronous multiprocessing python-multiprocessing python-asyncio

我正在设置一个函数以异步启动一个新的进程,以运行一个非常占用CPU的函数。大多数文档都没有对此进行全面介绍,而且我拼凑的内容似乎并不是异步工作的。

我有一个函数procManager,该函数接受一个函数,传递给该函数的args以及用于基本日志记录的对象名称。

async def procManager(f,a,o):
    print(f"{o} started at {time.strftime('%X')}")
    p = Process(target=f, args=(a,))
    p_parent = os.getppid()   # parent process
    p_curr = os.getpid()     # current process
    print("parent process:", p_parent)
    print("current process:", p_curr)
    p.start()
    p.join()
    print(f"{o} finished at {time.strftime('%X')}")
    print("=========")

我有这个cpu重型函数,它在我传递到def procManager并生成新进程的networkX图形上运行Louvain的社区检测。

def community(cg):
    start = timer()
    partition = c.best_partition(cg) #default louvain community detection
    v = {} #create dict to group nodes by community
    for key, value in sorted(partition.items()):
        v.setdefault(value, []).append(key)
    stop = timer()
    print(stop-start)

主要功能看起来像这样。我要初始化2个分别为3000和1000个节点的图形A和B,平均度为5。我正在使用Jupyter笔记本运行此图形,因此我使用await main()而不是asyncio.run

A = nx.barabasi_albert_graph(3000,5)  
B = nx.barabasi_albert_graph(1000,5)  

async def main():
    task1 = asyncio.create_task(
        procManager(community, A, "A"))

    task2 = asyncio.create_task(
        procManager(community, B, "B"))

    print("async start")

await main()

我想做的是异步处理A和B(即同时开始),但处理不同。当前输出看起来像这样,其中A和B在新的进程中处理,但是正在阻塞。我需要以异步方式计算A和B社区,因为它们将由RabbitMQ流触发,并且响应必须是非阻塞的。

async done
A started at 06:03:48
parent process: 5783
current process: 12121
11.424800566000158
A finished at 06:03:59
=========
B started at 06:03:59
parent process: 5783
current process: 12121
0.037437027999885686
B finished at 06:03:59
=========

希望你们能提供帮助!

2 个答案:

答案 0 :(得分:1)

您的问题是const resFunc2 = (await Promise.all([ func1(), func2(), ]))[1]; 方法。它会阻塞,直到过程完成为止。另外,您甚至不需要const [resFunc2] = await Promise.all([ func2(), func1(), ]); 。看一下这个简单的例子:

join()

这应该使您对如何解决问题有所了解。希望对您有所帮助!

答案 1 :(得分:-1)

关于Asyncio,您需要使用asyncio.create_task方法。此方法的窍门是,您只应指定已声明为异步的函子。为了运行它们,您应该使用await asyncio.gather

示例为:

import asyncio

async def print_hello(name):
    print("Hello! {}".format(name))

name_list = ["billy", "bob", "buffalo bob"]

for item in name_list:
    await asyncio.gather(print_hello(item))

使用asyncio创建和运行子流程的最简单形式是此处概述的create_task方法:Asyncio Docs

希望这会有所帮助!