当前位置: 首页 > 知识库问答 >
问题:

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

罗法
2023-03-14

我不熟悉Python中的多重处理,并试图弄清楚我是否应该使用池或进程来调用两个函数异步。我有两个函数进行curl调用,并将信息解析成两个独立的列表。根据互联网连接的不同,每个功能可能需要大约4秒钟。我意识到瓶颈在于ISP连接,多重处理不会加快速度,但是让它们都启动异步会很好。另外,这对我来说是一次很好的学习经历,因为我以后会更多地使用它。

我读过Python多处理。池:何时使用应用,apply_async或地图?这很有用,但我仍然有自己的问题。

所以我可以做的一个方法是:

def foo():
    pass

def bar():
    pass

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

p1.start()
p2.start()
p1.join()
p2.join()

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

另一种选择是:

def foo():
    pass

def bar():
    pass
pool = Pool(processes=2)             
p1 = pool.apply_async(foo)
p1 = pool.apply_async(bar)

对于这个实现,我的问题是:1)我需要一个池吗。close(),池。join()?2) 我会游泳。map()在我得到结果之前把它们全部完成?如果是这样,它们仍然异步运行吗?3) 你会怎么做。apply_async()不同于使用池执行每个进程。apply()4)这与之前的流程实现有何不同?

共有2个答案

江亮
2023-03-14

因为您是从curl调用中获取数据,所以您是IO绑定的。在这种情况下,希腊人可能会派上用场。这些实际上既不是进程也不是线程,而是协程——轻量级线程。这将允许您异步发送HTTP请求,然后使用多重处理。池以加速CPU绑定部分。

1) 因为连接会阻塞,直到调用过程完成。。。这是否意味着p1进程必须在p2进程启动之前完成?

是,p2。join()p1之后调用。join()已返回,表示p1已完成。

1) 我需要游泳池吗。close(),池。加入

您可能会在不执行close()join()的情况下得到孤立的进程(如果进程不可靠地服务)

2)pool.map()在我得到结果之前完成它们吗?如果是这样,他们仍然运行异步?

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

3) 你会怎么做。apply_async()不同于使用池执行每个进程。应用()

pool.apply()是阻塞的,所以基本上您会同步进行处理。

4) 这与之前的流程实现有何不同

很有可能在应用bar之前,一个工人已经用foo完成了所有工作,因此您可能最终会让一个工人完成所有工作。此外,如果您的一个工作人员死亡Pool会自动生成一个新的工作人员(您需要重新应用该任务)。

总而言之:我更愿意使用Pool——它非常适合生产者-消费者案例,并负责所有任务分配逻辑。

黄沈浪
2023-03-14

您列出的两个场景完成了同样的事情,但方式略有不同。

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

第二个场景启动两个进程(称为Q1和Q2),首先在Q1或Q2上启动foo,然后在Q1或Q2上启动bar。然后代码等待,直到两个函数调用都返回。

所以净结果实际上是相同的,但是在第一种情况下,您可以保证在不同的进程上运行foobar

至于您对并发的具体问题,在进程完成之前,进程上的. start()方法确实会阻塞,但是因为您在P1和P2上都调用了. start()(在您的第一种场景)在加入之前,那么两个进程将异步运行。然而,解释器将等待P1完成后再尝试等待P2完成。

对于有关池场景的问题,技术上应该使用pool。close()但这取决于您以后可能需要它做什么(如果它只是超出了范围,那么您不必关闭它)<代码>池。map()是一种完全不同的动物,因为它跨池进程(异步)将一组参数分配给同一个函数,然后等待所有函数调用完成,然后返回结果列表。

 类似资料:
  • 我有一个图像路径列表,我想在进程或线程之间划分,以便每个进程处理列表的某些部分。处理包括从磁盘加载图像,进行一些计算并返回结果。我正在使用Python 2.7 下面是我如何创建辅助进程 我所面临的问题是,当我在initializer函数中记录初始化时间时,我知道worker不是并行初始化的,而是每个worker都以5秒的间隔初始化,下面是供参考的日志 我尝试过使用将同时启动辅助线程 我知道Wind

  • 问题内容: 是否有用于工作线程的类,类似于多处理模块的类? 我喜欢例如并行化地图功能的简单方法 但是,我希望这样做而不会产生新流程的开销。 我知道。但是,在我的用例中,该函数将是绑定的函数,python包装器将在实际函数调用之前为其释放。 我必须编写自己的线程池吗? 问题答案: 我刚刚发现模块中实际上 有一个基于线程的Pool接口,但是它有些隐藏并且没有正确记录。 可以通过导入 它是使用包装Pyt

  • 我知道子进程是进程,而不是线程。我使用了错误的语义,因为大多数人在谈到“多线程”时都知道您的意图。所以我会把它保留在标题中。 想象一下这样一个场景:使用一个自定义函数或模块,您连续有多个类似和复杂的事情要做。使用所有可用的核心/线程(例如8/16)非常有意义,这就是的目的。 理想情况下,您需要多个同时工作的人员,并向一个控制器发送/从一个控制器发送/回调消息。 node cpool、fork po

  • 我有下面的代码片段,它试图在多个子进程之间分割处理。 while循环中的主进程正在调用search函数,如果队列达到阈值计数,则处理池将映射到进程函数,其中作业来自队列。我的问题是,python多处理池是在执行期间阻塞主进程,还是立即继续执行?我不想遇到这样的情况,“has_jobs_to_process()”的计算结果为true,并且在处理作业的过程中,另一组作业的计算结果为true,并且再次调

  • 问题内容: 我想使用multiprocessing.Pool,但是multiprocessing.Pool不能在超时后中止任务。我找到了解决方案,并对其进行了一些修改。 主要修改-使用 sys.exit(1) 退出工作进程。它杀死了工作进程并杀死了工作线程,但是我不确定这个解决方案是否很好。当进程因正在运行的作业而终止时,我会遇到哪些潜在的问题? 问题答案: 停止正在运行的作业没有隐含的风险,操作

  • 我甚至不能使用Python 2.7中运行的多重处理包(使用spyder作为窗口上的用户界面)进行并行处理的最简单的例子,我需要帮助解决这个问题。我已经运行了conda更新,所以所有的包都应该是最新的和兼容的。 即使多处理软件包文档(如下所示)中的第一个示例也不起作用,它会生成4个新进程,但控制台只是挂起。在过去的3天里,我已经尝试了我能找到的一切,但是没有一个不挂起就运行的代码能够将我25%以上的