设置正在运行的进程与任务集的关联性失败

设置正在运行的进程与任务集的关联性失败

我试图将进程限制为给定数量的 CPU 核心。根据任务集手册页和本文档,以下应该有效:

[fedora@dfarrell-opendaylight-cbench-devel ~]$ taskset -pc 0 <PID>
pid 24395's current affinity list: 0-3
pid 24395's new affinity list: 0

简单地说——这是行不通的。将进程置于负载下并观察top,它的 CPU 使用率约为 350%(与没有任务集时相同)。它应该最大为 100%。

我可以在taskset -c 0 <cmd to start process>进程生成时正确设置亲和力。cpulimit -p <PID> -l 99还使用有点作品。在这两种情况下,将进程置于相同的负载下会导致 CPU 使用率达到 100%。

这里出了什么问题?

答案1

更新:较新版本的任务集有一个-a/--all-tasks选项,“对给定 pid 的所有任务(线程)进行操作”,并且应该解决我下面显示的行为。

我编写了一个 Python 脚本,它只是启动一些线程并消耗 CPU 周期。这个想法是针对它测试任务集,因为它非常简单。

#!/usr/bin/env python

import threading

def cycle_burner():
    while True:
        meh = 84908230489 % 323422

for i in range(3):
    thread = threading.Thread(target=cycle_burner)
    print "Starting a thread"
    thread.start()

仅运行 Python 脚本就消耗了大约 150% 的 CPU 使用率。

[~/cbench]$ ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread

使用任务集启动我的 Python 脚本可以按预期工作。查看 top 显示 Python 进程的使用率为 100%。

[~/cbench]$ taskset -c 0 ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread

有趣的是,启动 Python 脚本,然后立即使用任务集设置刚刚启动的进程的亲和力会将进程限制为 100%。从输出中请注意,Linux 调度程序在生成 Python 线程之前完成了 Bash 命令的执行。因此,Python 进程启动,然后将其设置为在 CPU 0 上运行,然后生成其线程,该线程继承了正确的关联性。

[~/cbench]$ ./burn_cycles.py &; taskset -pc 0 `pgrep python`
[1] 8561
pid 8561's current affinity list: 0-3
pid 8561's new affinity list: 0
Starting a thread
[~/cbench]$ Starting a thread
Starting a thread

该结果与此方法形成对比,后者完全相同,但允许在设置 Python 进程的关联性之前生成 Python 线程。这复制了我上面描述的“任务集不执行任何操作”结果。

[~/cbench]$ ./burn_cycles.py &
[1] 8996
[~/cbench]$ Starting a thread
Starting a thread
Starting a thread
[~/cbench]$ taskset -pc 0 `pgrep python`
pid 8996's current affinity list: 0-3
pid 8996's new affinity list: 0

这里出了什么问题?

显然,在父进程的亲和力更改之前生成的线程不会继承其父进程的亲和力。如果有人可以编辑解释这一点的文档链接,那将会很有帮助。

答案2

我认为您需要每个线程调用一次任务集,即使用ps -eL而不是pgrep并将其通过管道传递给taskset -cp 0

ps -eLo cmd,tid | grep python | perl -pe 's/.* (\d+)$/\1/' | xargs -n 1 taskset -cp 0

这会调用所有线程 ID 的任务集。

答案3

尝试数字--physcpubind(或-C) 代替。手册页说:

...该政策是为命令而制定的,并由其所有子项继承。

(在最近的版本中taskset还有一个-a选项,Sets or retrieves the CPU affinity of all the tasks (threads) for a given PID.但不清楚这是否也适用于启动的任务的子进程,taskset而不是修改已经运行的进程)

答案4

我成功地使用了taskset-a选项。我有一个名为 videoconverterd 的服务器,它消耗大量 CPU;top节目

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 8991 root      20   0 1299472 346724  47380 S 385.7  4.3  42:41.37 videoconverterd

运行后taskset -apc 0 8991,CPU负载下降至

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 8991 root      20   0 1221832 293344  47380 S  99.7  3.7  49:13.28 videoconverterd

我运行的是 CentOS 7,taskset版本为 2.23.2。

相关内容