我试图将进程限制为给定数量的 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
Run Code Online (Sandbox Code Playgroud)
简单地说——这行不通。将进程置于负载和监视之下top
,它的 CPU 使用率约为 350%(与没有任务集时相同)。它应该最大为 100%。
我可以通过taskset -c 0 <cmd to start process>
在进程生成时正确设置亲和力。使用cpulimit -p <PID> -l 99
也有点工作。在这两种情况下,将进程置于相同的负载下会导致 CPU 使用率达到 100%。
这里出了什么问题?
更新:较新版本的 taskset 有一个-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()
Run Code Online (Sandbox Code Playgroud)
仅仅运行 Python 脚本就消耗了大约 150% 的 CPU 使用率。
[~/cbench]$ ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
Run Code Online (Sandbox Code Playgroud)
使用任务集启动我的 Python 脚本按预期工作。观看顶部显示 Python 进程的使用率为 100%。
[~/cbench]$ taskset -c 0 ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
Run Code Online (Sandbox Code Playgroud)
有趣的是,启动 Python 脚本,然后立即使用 taskset 设置刚刚启动的进程的亲和性将进程限制在 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
Run Code Online (Sandbox Code Playgroud)
该结果与此方法形成对比,该方法完全相同,但允许 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
Run Code Online (Sandbox Code Playgroud)
这里出了什么问题?
显然,在父进程的亲缘关系改变之前产生的线程不会继承其父进程的亲缘关系。如果有人可以在解释这一点的文档的链接中进行编辑,那将会很有帮助。