我在一台 Ubuntu Linux 主机上使用多个带有不同操作系统的 VirtualBox VM 进行开发。有时我的脚本出错并开始加载 100% 的 VM CPU。当一台 VM 加载 100% 的 CPU 时,我甚至无法使用主机系统 - 它很慢!
然后我必须打开 top(非常慢),查看 VirtualBox 进程是否使用了 240% 的 CPU,然后打开每个 VM 窗口,直到找到占用大量 CPU 的 VM 并终止进程。我不想终止使用大量 CPU 的整个 VirtualBox 进程。
我的所有虚拟机都配置为仅使用一个 CPU 核心,执行上限为 100%。我的 CPU 是 AMD FX 8370(8 核,16 线程),我的主机在 SSD raid 10 上运行,文件系统正确对齐。我在 Windows 主机环境中吗?当然不是!那么为什么我会遇到速度变慢的情况?
可能是因为所有 VirtualBox VM 都只分配了第一个核心(就像 Windows 通常那样)?如何检查这一点以及如何让每个 VM 使用每个核心?也许还有其他猜测?
也许这个问题只是:如何在 Linux 中将任何应用程序分配给特定的核心?
答案1
我无法回答你的问题,但至少我可以减轻你的痛苦。
如果你从命令行启动每个虚拟机,例如
VBoxManage startvm Name_of_VM --type headless
然后带有选项的 top 命令-c
还会显示启动该进程的完整命令。这样您就可以立即识别罪魁祸首进程,并使用其k
内部的选项将其杀死top
(您必须提供刚刚识别出的要杀死的进程的编号)。
好消息是,即使您从 GUI 而不是从 CLI 启动所有 VM,这也能起作用。
编辑:
再想想,也许我知道你的问题的答案。我不确定这是否真的是你正在寻找的,在这种情况下,请告诉我。
将进程的执行限制在预先指定的核心上的 Linux 实用程序是taskset
。您应该默认拥有它,如果没有,请检查软件包util-linux
。您可以显示进程亲和力(IE(允许运行的 CPU 列表)通过
taskset -cp Process_ID
(该p
标志指定后面跟着一个进程号,该c
标志将字符串替换为 CPU 核心的十六进制表示形式,这将是默认值)。
你可以指定一个已经运行的进程仅在核心 0 和 1 上运行,例如,通过
taskset -cp 0,1 Process_ID
或者仅通过以下方式在核心 0 上启动新程序:
taskset -c 0 VBoxManage startvm Name_of_VM --type headless
两个注意事项:首先,将进程限制在单个 CPU 上运行并不意味着它将是该 CPU 上运行的唯一进程:所有亲和性包括该 CPU 的进程都将在一段时间内在该 CPU 上运行。如果您想保留一个给定的 CPU 供您设置的进程独占使用taskset
,则必须使用isolcpus
参数将给定的 CPU 与内核调度程序隔离。只需将参数 isolcpus=[cpu_number] 添加到引导加载程序的 Linux 内核命令行即可。
此外,您应该注意,将进程限制在单个 CPU 上并不一定像total solution
您想象的那样。CPU 使用任何类型的外围设备,在特定情况下,它们可能会卡住,因为相关外围设备变得不可用,这会导致 CPU 循环处理其请求,总线甚至外围设备也可能因请求而过载。举个例子?我使用在 Wine 下运行的 Sonos 控制器;当我激活 VPN 时,它会与加利福尼亚的总部断开连接,并不断向我的系统发送大量网络请求。这与限制在单个 CPU 上无关。
答案2
在 MariusMatutiae 的回答的帮助下,我终于成功编写了“扩展器”脚本,将所有启动的 VirtualBox VM 扩展到不同的核心。此外,它还对 VMware VM 执行相同的操作。
要使用此脚本,您的所有虚拟机都应为单核(可在设置中设置)。否则,您可以通过修改 grep regexp 来排除它们。
#!/bin/bash
#getting possible affinity lists
AFFINITY=($(taskset -cp 1 | sed 's/.*\([0-9]\)\+[-]\([0-9]\+\).*/\1 \2/'))
echo Detected min_cpu: ${AFFINITY[0]}, max_cpu: ${AFFINITY[1]}.
CURRENT_AFFINITY=${AFFINITY[1]};
ps -Af | grep -i "[V]irtualBox.*comment\|.*[.]vm[x]" | awk -F" " '{ print $2}' |
# Iterating backwards because I think that farther cpus are less loaded. Maybe I am wrong
while read pid
do
echo Setting $pid to cpu $CURRENT_AFFINITY
taskset -cp $CURRENT_AFFINITY $pid
#loop stuff
let CURRENT_AFFINITY=CURRENT_AFFINITY-1;
if [[ "$CURRENT_AFFINITY" -lt ${AFFINITY[0]} ]];
then
CURRENT_AFFINITY=${AFFINITY[1]};
fi
done
如果您希望它只适用于 VirutalBox VM,请[V]irtualBox.*comment\|
从 grep 模式中删除。如果您希望它只适用于 VMware VM,请\|.*[.]vm[x]
从 grep 模式中删除。
刚应用此脚本后,您会看到所有虚拟机都出现延迟,持续几秒钟。然后一切都恢复正常,并按预期运行。
现在,即使超载,虚拟机也不会占用我的 CPU,而 Firefox 也很乐意占用所有 CPU。但那是另一个故事…… :/