
我在一台 Ubuntu Linux 主機上使用許多具有不同作業系統的 VirtualBox 虛擬機器進行開發。有時我的腳本會出錯並開始載入 100% 的 VM cpu。當一台虛擬機器加載 100% cpu 時,我甚至無法使用主機系統 - 速度很慢!
然後我必須打開頂部(非常慢),看到 VirtualBox 進程使用了 240% 的 CPU,然後打開每個 VM 窗口,直到找到載入 cpu 的 VM 並終止進程。我不想殺死整個使用大量CPU的VirtualBox進程。
我的所有虛擬機器都配置為僅使用一個 cpu 核心,執行上限為 100%。我的 CPU 是 AMD FX 8370(8 核,16 執行緒),我的主機在 SSD raid 10 上運行,檔案系統正確對齊。我是在windows主機環境下嗎?當然不是!那為什麼我會遇到速度變慢的情況呢?
也許是因為所有 VirtualBox VM 只分配第一個核心(就像 Windows 通常那樣)?如何檢查以及如何讓每個虛擬機器使用每個核心?也許還有其他一些猜測?
也許這個問題只是:如何將任何應用程式分配給 Linux 中的特定核心?
答案1
我無法回答你的問題,但至少我可以減輕你的痛苦。
如果您從命令列啟動每個虛擬機,例如
VBoxManage startvm Name_of_VM --type headless
那麼帶有該選項的 top 指令-c
也會顯示啟動該進程的完整指令。這樣您就可以立即識別罪魁禍首進程,並使用其k
內部的選項殺死它top
(您必須提供您剛剛識別出的要殺死的進程的編號)。
好處是,即使您從 GUI 而不是從 CLI 啟動所有虛擬機,這仍然有效。
編輯:
再想想,也許我知道你問題的答案。我不確定這真的是您要尋找的東西,在這種情況下請告訴我。
將進程的執行限制在預先指定的核心的 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 的回答的幫助下,我終於成功編寫了「傳播器」腳本,將所有啟動的虛擬機器虛擬機器傳播到不同的核心。此外,它也對 VMware 虛擬機器執行相同的操作。
要使用此腳本,您的所有虛擬機器都應該是單核心的(可以在設定中設定)。否則,您可以透過修改 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 模式中移除。
套用此腳本後,您可以看到所有虛擬機器中出現幾秒鐘的延遲。然後一切都會變得很好並且按預期工作。
現在,即使超載,VM 也無法吃掉我的 cpu,而 firefox 真的很樂意吃掉這一切。但這是另一個故事了......:/