在Windows上降低多进程池(multiprocessing.Pool)的进程优先级

8

我使用multiprocessing.Pool()来并行处理一些繁重的Pandas处理,但发现它有点太成功了。我的CPU使用率达到了100%,整个计算机变得非常不响应。甚至鼠标都难以使用。

我可以使用以下代码更改进程的优先级。

import psutil
p = psutil.Process(os.getpid())
p.nice = psutil.BELOW_NORMAL_PRIORITY_CLASS

然而,当我查看Windows任务管理器时,我发现只有主要的python.exe进程被降低到了低于正常的优先级。

是否有一种好的方法来降低池进程的优先级?


你尝试过将你展示的代码片段放在worker函数内部吗? - Lev Levitsky
为什么不只生成较少的进程? - acushner
@acushner 我暂时将池大小设置为7来进行了一些修改,这样就“修复”了它。但我想知道是否有更好的解决方案。 - JasonEdinburgh
@levitsky 我原本预计psutil代码会重复运行时很慢,所以我没有尝试过。现在我会去尝试一下。如果有一种方法可以仅对每个进程执行一次,那就更好了。我认为可能有更好的方法来实现这一点,比如指示池使用低优先级进程。 - JasonEdinburgh
3个回答

7

您可以在生成子进程后尝试设置进程优先级。例如:

import psutil

# spawn children and/or launch process pool here

parent = psutil.Process()
parent.nice(psutil.BELOW_NORMAL_PRIORITY_CLASS)
for child in parent.children():
    child.nice(psutil.BELOW_NORMAL_PRIORITY_CLASS)

是的!谢谢你。我不得不稍微修改一下。你可能想为其他人修改你的答案。 - JasonEdinburgh
parent = psutil.Process() parent.nice = psutil.BELOW_NORMAL_PRIORITY_CLASS for child in parent.get_children(): child.nice = psutil.BELOW_NORMAL_PRIORITY_CLASS - JasonEdinburgh
我发现另一种方法是使用ProcessHacker2。http://processhacker.sourceforge.net/ - JasonEdinburgh
1
"child.nice = value" 在 psutil 2.0.0 中已被弃用。 - Giampaolo Rodolà

2

只需在生成子进程之前设置父进程优先级,即可实现与@Giampaolo Rodolà的答案相同的结果:

将父进程优先级设置为高于默认值即可。

示例代码:

import psutil

parent = psutil.Process()
parent.nice(psutil.BELOW_NORMAL_PRIORITY_CLASS)
# the rest of your code

子进程将继承父进程的优先级。但是,如果要将父进程设置为与子进程不同的优先级,则需要使用@Giampaolo Rodolà提供的代码。

原始答案:最初的回答


1

Python文档指出,创建进程池时可以指定进程数。如果不指定,则默认为os.cpu_count。因此,您会得到预期的行为,即使用所有可用的逻辑核心。反过来,计算机变得无响应。

可能更好的方法是通过控制创建的进程数来做一些更简单的事情。一个经验法则是保留2到4个逻辑核心用于交互式处理。

此外,Python文档指出:“这个数字[os.cpu_count()]不等同于当前进程可以使用的CPU数量。可用CPU数量可以通过len(os.sched_getaffinity(0))获得。

还有几个细节需要处理。我已经在这里的gist中尝试捕捉它们。你所需要做的就是为你特定的用例更改LOGICAL_CORES_RESERVED_FOR_INTERACTIVE_PROCESSING。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接