python - 测试 niceness 是否被正确应用

标签 python linux unix multiprocessing nice

我正在尝试将某些流程优先于其他流程。这是我正在使用的主要脚本,模拟一个 CPU 密集型进程:

simple_app.py

import os
from multiprocessing import Pool, cpu_count

def f(x):
    while True:
        x*x

if __name__ == '__main__':

    cpu = cpu_count()
    pid = os.getpid()

    print('-' * 20)
    print('pid: {}'.format(pid))
    print('Utilizing {} cores'.format(cpu))
    print('Current niceness: {}'.format(os.nice(0)))
    print('-' * 20)

    pool = Pool(cpu)
    pool.map(f, range(cpu))

我的下一步是生成大量(具体来说,在本例中为 9 个)运行此代码的进程:

simple_runner.sh

# Start with lowest priority
nice -19 python3 simple_app.py &
# Much higher priority
nice -0 python3 simple_app.py &
# Lower priority spawned
nice -10 python3 simple_app.py &
# Higher priority again
nice -7 python3 simple_app.py &
# Highest priority yet
nice -1 python3 simple_app.py &
# Highest priority yet
nice -0 python3 simple_app.py &
# Highest priority yet
nice -0 python3 simple_app.py &
# Highest priority yet
nice -0 python3 simple_app.py &
# Highest priority yet
nice -0 python3 simple_app.py

然后我监控每个进程,报告子 CPU 利用率,在这里:

process_reporting_server.py

import os
import time
import argparse
import pprint
from multiprocessing import Pool, cpu_count

import psutil

def most_recent_process_info(pid, interval=0.5):
    while True:
        proc = psutil.Process(pid)
        children_cpu_percent = [child.cpu_percent(interval) for child in proc.children()]
        children_cpu_percent_mean = sum(children_cpu_percent) / len(children_cpu_percent) if children_cpu_percent else -1.
        print('Time: {}, PID: {}, niceness: {}, average child CPU percent: {:.2f}'.format(
            time.ctime(),
            pid,
            proc.nice(),
            children_cpu_percent_mean)
        )

if __name__ == '__main__':

    parser = argparse.ArgumentParser()
    parser.add_argument('-p', '--pids', type=str, help='Whitespace-delimited string containing PIDs', dest='pids')
    parser.add_argument('-s', '--seconds', type=int, help='Seconds to sleep', default=10, dest='seconds')
    args = parser.parse_args()

    pids = list(map(int, args.pids.split()))

    pool = Pool(len(pids))
    pool.map(most_recent_process_info, pids)

我想看看给出较低 niceness 值的进程是否真的被优先考虑。所以这就是我所做的:

运行simple_app_runner.sh:

$ ./simple_app_runner.sh 
--------------------
pid: 45036
Utilizing 8 cores
Current niceness: 0
--------------------
--------------------
pid: 45030
Utilizing 8 cores
Current niceness: 19
--------------------
--------------------
pid: 45034
Utilizing 8 cores
Current niceness: 1
--------------------
--------------------
pid: 45032
Utilizing 8 cores
Current niceness: 10
--------------------
--------------------
pid: 45033
Utilizing 8 cores
Current niceness: 7
--------------------
--------------------
pid: 45037
Utilizing 8 cores
Current niceness: 0
--------------------
--------------------
pid: 45038
Utilizing 8 cores
Current niceness: 0
--------------------
--------------------
pid: 45031
Utilizing 8 cores
Current niceness: 0
--------------------
--------------------
pid: 45035
Utilizing 8 cores
Current niceness: 0
--------------------

然后,这是报告:

$ python3 process_reporting_server.py -p '45036 45030 45034 45032 45033 45037 45038 45031 45035'

稍微清理一下并使用 pandas 进行分析,我们发现在五分钟的时间间隔内,指定的良好度似乎并不重要:

>>> df.groupby('nice')['mean_child_cpu'].max()
nice
0.0     10.50
1.0      9.75
7.0      8.28
10.0     8.50
19.0    21.97

我在这里完全遗漏了什么吗?为什么我指定的 niceness 似乎不会影响 CPU 资源的优先级排序?

最佳答案

我认为您没有遗漏任何东西。我的经验是,最重要的过程得到优先考虑,其他人都在为剩下的事情而战。如果仅将一个进程重新设置为 -1 并将其余进程保留为 -0,您可能会得到相同的结果(对于像这样的纯 cpu 绑定(bind)进程)。

而且,这是因为人们通常真的不希望优先级排序像我们有时期望的那样硬核。就像现在我发布这个时我的平均负载超过 200,并且有一堆 reniced(更高优先级)进程在运行。如果所有这些过程都真的很麻烦,那么它就不会“很好”。我喜欢这样,我仍然可以在所有 CPU 负载持续的情况下使用我的浏览器。

有一次我的印象是你可以改变优先级队列,至少在一些 unix 上是这样。我依稀记得我的一些客户要求我们这样做,我们(系统管理员团队)说“这不是一个好主意”,客户要求我们这样做,我们就这样做”,然后客户要求我们撤消它。调度是棘手的事情。

这里介绍了幕后发生的事情:http://www.cs.montana.edu/~chandrima.sarkar/AdvancedOS/SchedulingLinux/index.html 请特别注意底部部分 - “该算法不能很好地扩展”,它与我的第一段密切相关。

关于python - 测试 niceness 是否被正确应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53524339/

相关文章:

python -\n 在 python 中的工作

python - 如何在 Linux 中查找 firefox 插件路径

linux - 将 awk 结果存储为 bash ${} 数据格式

linux - 删除文件名开头带有数字的文件

c++ - 微软 Visual Studio : Windows and Unix project source code compatibility

python - 迁移学习——尝试在内存不足的 RTX 2070 上重新训练 efficientnet-B07

python - reshape pandas DataFrame 以在嵌套字典中导出

linux - centos 7 AWS(使用 ssh key 和密码登录)

linux - 交叉编译时无法通过 ./configure 访问 Buildroot 暂存库。测试编译失败。

Linux:根据匹配从文本文件中提取指定行数