将Java线程绑定到核心上

5

我正在启动的Java进程是Elasticsearch,它创建了许多线程。我使用 ps HuH p <pid> | wc -l 来检查它们。

这是我获取Elasticsearch pid的方法:

ES=`jps | egrep 'Elasticsearch' | awk '{print $1}'`

我使用以下python脚本将给定pid的所有线程固定到一组核心上。

#!/usr/bin/env python
import os
import argparse

def task_set(pid, core):
    print "pinning all threads of pid: ", pid, " to cores: ", core
    os.system('taskset -apc '+str(core)+' ' +str(pid)+' >/dev/null')

def main(args):
    experiments = ["1B", "2B", "1B3S", "2B2S", "1S", "2S", "3S", "4S"]
    which = args.id[0]
    idx = experiments.index(which)
    PC = ["0", "0,1", "0,2,3,4", "0,1,2,3", "2", "2,3","2,3,4", "2,3,4,5"]
    task_set(args.pid[0], PC[idx])
if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('--pid', nargs=1, help='appid')
    parser.add_argument('--id', nargs=1, help='core')
    args = parser.parse_args()
    main(args)

然而,当我使用命令top -H -p <pid>查看并监控核心分配时,大部分时间它并不遵循规定。

这里有什么我漏掉的吗?JVM需要在这方面做些什么吗?

还有其他方法可以将线程钉在核心上吗?


1
不,JVM本身不会影响线程亲和性。为了简化问题,将其拆分为两个部分:首先检查命令行中taskset命令是否有效,如果有效,则调试Python脚本。 - apangin
我也尝试了那部分,但没有成功。此外,有多个Java线程。我怎么知道有多少是真正的“工作”线程? - tandem
顺便问一下,taskset 命令中的 a 参数是用来做什么的?我的 Linux 发行版没有这个参数。在 man 中也没有看到它。 - apangin
我不确定你的意思。taskset 对我来说很好用。你能澄清一下你运行的命令以及如何检查它是否无法工作吗? - apangin
2
是的,这种情况是可能存在的。我不会依赖于 top 来验证进程亲和性。如果 taskset 在没有 CPU 列表参数的情况下调用并打印出预期的绑定,则我会认为脚本已成功。 - apangin
显示剩余7条评论
1个回答

0

taskset 将正常工作。但是,如果进程处于睡眠状态,则其当前 CPU 不会切换到新的 CPU。

cat /proc/<PID>/status | grep State:

为了解决这个问题,你可以这样做

kill -SIGSTOP <PID>
kill -SIGCONT <PID>

这将强制进程退出睡眠状态并确保 CPU 切换。tophtop 然后将正确显示该值。


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