我正在开发嵌入式 Linux 系统(kernel-5.10.24)。我正在尝试让一个进程完全占用一个CPU而不被调度出去。
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char **argv)
{
int cpus = 0;
int i = 0;
cpu_set_t mask;
struct sched_param schedp;
cpus = sysconf(_SC_NPROCESSORS_ONLN);
printf("cpus: %d\n", cpus);
CPU_ZERO(&mask);
CPU_SET(1, &mask);
if (sched_setaffinity(0, sizeof(mask), &mask) == -1) {
printf("Set CPU affinity failue, ERROR:%s\n", strerror(errno));
return -1;
}
memset(&schedp, 0, sizeof(schedp));
schedp.sched_priority = sched_get_priority_max(SCHED_FIFO);
if (sched_setscheduler(0, SCHED_FIFO, &schedp) == -1) {
perror("error: Failed to set the thread priority");
return -1;
}
while(1)
;
return 0;
}
我将 SCHED_FIFO(优先级 99)绑定到 CPU1。
我也sysctl -w kernel.sched_rt_runtime_us=1000000
。
当我检查时/proc/sched_debug
,/proc/PIDxxx/status
我发现 RT 进程仍在安排中,nonvoluntary_ctxt_switches
并且增加了。
那么怎样才能让一个进程完全占用CPU而不被调度呢?
答案1
我找到了一种方法可以让一个进程完全占用CPU而不被调度出去。
除了我在问题中所做的之外,我还在isolcpus=1 rcu_nocbs=1 nosoftlockup
内核命令行中进行了设置。
有了它,nonvoluntary_ctxt_switches
流程就不会改变。
我不确定我的方法是一个好方法,我发现有内核日志说类似
[ 271.620046] BUG: workqueue lockup - pool cpus=1 node=0 flags=0x0 nice=0 stuck for 219s!
[ 271.620083] Showing busy workqueues and worker pools:
[ 271.620088] workqueue events: flags=0x0
[ 271.620093] pwq 2: cpus=1 node=0 flags=0x0 nice=0 active=1/256 refcnt=2
[ 271.620110] pending: cache_reap
还有其他更好的方法吗?