我正在做什么的Python多处理过程或池?

dma*_*man 37 python multithreading asynchronous multiprocessing

我是Python的多处理新手,试图弄清楚我是否应该使用Pool或Process来调用两个函数async.我有两个函数进行curl调用并将信息解析为2个单独的列表.根据互联网连接,每个功能可能需要大约4秒.我意识到瓶颈在于ISP连接,多处理不会加速它,但让它们开始异步会很好.另外,对于我来说,进入python的多处理是一个很好的学习经验,因为我将在以后使用它.

我读过Python multiprocessing.Pool:何时使用apply,apply_async或map?它很有用,但仍然有我自己的问题.

所以我能做到的一种方法是:

def foo():
    pass

def bar():
    pass

p1 = Process(target=foo, args=())
p2 = Process(target=bar, args=())

p1.start()
p2.start()
p1.join()
p2.join()
Run Code Online (Sandbox Code Playgroud)

我对此实现的问题是:1)由于连接阻塞直到调用进程完成...这是否意味着p1进程必须在p2进程启动之前完成?我总是理解.join()与pool.apply()和pool.apply_sync().get()相同,其中父进程在当前运行完成之前无法启动另一个进程(任务).

另一种选择是:

def foo():
    pass

def bar():
    pass
pool = Pool(processes=2)             
p1 = pool.apply_async(foo)
p1 = pool.apply_async(bar)
Run Code Online (Sandbox Code Playgroud)

我对此实现的问题是:1)我是否需要pool.close(),pool.join()?2)在我得到结果之前,pool.map()会使它们全部完整吗?如果是这样的话,他们还在跑吗?3)pool.apply_async()与使用pool.apply()执行每个进程有何不同4)这与使用Process的先前实现有何不同?

lmj*_*ns3 30

您列出的两个方案完成相同的操作但方式略有不同.

第一个场景启动两个独立的进程(称为P1和P2)并启动P1运行foo和P2运行bar,然后等待,直到两个进程完成各自的任务.

第二种情况开始两个过程(称为Q1和Q2),首先从fooQ1或Q2开始,然后从barQ1或Q2开始.然后代码等待,直到两个函数调用都返回.

所以,最终的结果实际上是一样的,但在第一种情况下你保证运行foo,并bar在不同的进程.

至于你对并发性的具体问题,.join()a Process上的方法确实会阻塞直到进程完成,但是因为你.start()在加入之前同时调用了P1和P2(在你的第一个场景中),所以两个进程都将异步运行.但是,在尝试等待P2完成之前,解释器将等待P1完成.

对于你关于池场景的问题,你应该在技术上使用,pool.close()但它取决于你之后可能需要它(如果它只是超出范围,那么你不需要关闭它).pool.map()是一种完全不同的动物,因为它在池进程中将一堆参数分配给同一个函数(异步),然后在返回结果列表之前等待所有函数调用完成.

  • 对于第一部分,它是否在多个内核上运行进程?当进程数>内核数时会发生什么? (2认同)

Mac*_*Gol 11

由于您从curl调用中获取数据,因此您受IO限制.在这种情况下,问候可能会派上用场.这些实际上既不是进程也不是线程,而是协同程序 - 轻量级线程.这将允许您发送异步HTTP请求,然后用于multiprocessing.Pool加速CPU绑定部分.

1)由于连接阻塞直到调用进程完成...这是否意味着p1进程必须在p2进程启动之前完成?

是的,p2.join()p1.join()返回意义p1完成后调用.

1)我需要一个pool.close(),pool.join()

如果没有这样做close(),你最终可能会join()遇到孤立的进程(如果进程无限期地服务)

2)在我得到结果之前,pool.map()会让它们全部完成吗?如果是这样的话,他们还在跑吗?

它们是异步运行的,但在map()完成所有任务之前会被阻塞.

3)pool.apply_async()与使用pool.apply()执行每个进程有何不同

pool.apply() 阻塞,所以基本上你会同步处理.

4)这与先前的Process实现有何不同

foo在你申请之前,工人很bar可能已经完成,所以你最终可能会找到一名工人完成所有的工作.此外,如果您的某个工作人员Pool自动死亡,则会生成一个新工作人员(您需要重新应用该任务).

总结一下:我宁愿选择Pool- 它非常适合生产者 - 消费者案例,并负责所有任务分配逻辑.

  • 我的意思是,`p2`将在'p1`加入后加入.抱歉,误解了.当然,只要适当的`start()`返回,两个进程就会启动. (2认同)