Иногда необходимо жестко контролировать, какие ядра процесс может занимать, например, чтобы тяжелые задачи не забивали сервер или чтобы критичные сервисы не конкурировали за ресурсы. В linux это решается утилитой
taskset, которая позволяет как изменять affinity уже работающих процессов, так и запускать новые с заданными ограничениями.1️⃣ Привязка уже запущенного процесса к выбранным ядрам. Для начала найдем PID процесса. Выберите любой удобный способ:
ps aux | grep myapp
pidof myapp
pgrep -f myapp
Посмотрим CPU в системе:
lscpu | grep -E 'CPU\(s\)|NUMA'
Пример вывода:
CPU(s): 8
NUMA node0 CPU(s): 0-7
Допустим, нам нужно посадить процесс на ядра 0–2. Для этого:
taskset -pc 0-2 1574
Пример результата:
pid 1574's current affinity list: 0-7
pid 1574's new affinity list: 0,1,2
Теперь процесс гарантированно не займет остальные ядра.
2️⃣ Запуск программы с ограничением по CPU. Это более практичный вариант: мы сразу запускаем процесс с нужными ограничениями. Но тут есть нюанс: taskset требует mask (битовой маски), а не списка ядер.
Как работает маска?
Каждое ядро - это один бит:
Ядро Маска
0 1
1 2
2 4
3 8
… …
Например:
ядра 1 и 2 = 2 + 4 = 6 → маска 0x06
Пример запуска с ограничением на одно ядро. Запустить программу только на ядре 0:
taskset 1 gzip hugefile
(маска 1 = ядро 0)
Пример: запуск на ядрах 2 и 3
Маска: 4 + 8 = 12 = c
taskset c gzip hugefile
3️⃣ Как быстро узнать маску для нужных ядер. Если не хочется считать вручную, то есть хитрый трюк. Назначаем список ядер любому процессу:
taskset -pc 4-5 $(pidof systemd-journald)
А теперь смотрим его маску:
taskset -p $(pidof systemd-journald)
Пример:
pid 412's current affinity mask: 30
Вот и маска.
4️⃣ Наглядный тест с помощью xz. Архиватор xz умеет использовать несколько потоков, и его хорошо видно в htop. Создаем тестовый файл:
dd if=/dev/urandom of=/tmp/testfile bs=1M count=200
Запускаем xz только на ядрах 0 и 1 (маска 3):
taskset 3 xz -T2 /tmp/testfile
Смотрим в htop и процесс будет занимать строго эти два ядра.
#linux #taskset
🧑💻 NetworkAdmin