Ubuntu 16.04是否官方支持SCHED_DEADLINE调度器?
解决Ubuntu 16.04(内核4.16)编译SCHED_DEADLINE测试程序时缺失定义的问题
你遇到的问题核心原因是:Ubuntu 16.04默认搭载的glibc版本(2.23)太旧,还没有正式支持SCHED_DEADLINE的用户空间接口——虽然你的内核4.16已经支持这个调度器,但用户态的头文件和库并没有提供对应的结构体(比如struct sched_attr)、宏(比如SCHED_DEADLINE)以及封装函数(比如sched_setattr)。
下面给你两种可靠的解决办法:
方法一:手动补充缺失的定义
直接在你的代码里添加内核层面的相关定义,这样就能绕过glibc版本的限制。参考内核头文件的标准定义,你可以在代码开头加入这些内容:
#define _GNU_SOURCE #include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sched.h> #include <stdint.h> // 手动定义SCHED_DEADLINE调度器常量 #ifndef SCHED_DEADLINE #define SCHED_DEADLINE 6 #endif // 定义sched_attr结构体(SCHED_DEADLINE依赖的核心结构体) struct sched_attr { uint32_t size; // 结构体大小,必须设置为sizeof(struct sched_attr) uint32_t sched_policy; // 调度策略,这里填SCHED_DEADLINE uint64_t sched_flags; // 调度标志,一般设为0即可 int32_t sched_nice; // 普通进程的nice值,SCHED_DEADLINE用不到,设为0 uint32_t sched_priority; // 实时进程优先级,SCHED_DEADLINE用不到,设为0 // SCHED_DEADLINE专属参数 uint64_t sched_runtime; // 任务每次可运行的最长时间(纳秒) uint64_t sched_deadline; // 任务必须完成的截止时间(相对于周期起点,纳秒) uint64_t sched_period; // 任务的运行周期(纳秒) }; // 如果glibc未声明sched_setattr函数,手动声明 #ifndef HAVE_SCHED_SETATTR int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags); #endif
之后你就可以像参考文档里的示例一样使用sched_setattr来设置SCHED_DEADLINE调度策略了,编译命令直接用:
gcc -o deadline_test deadline_test.c
方法二:直接调用系统调用(更稳妥)
如果手动定义结构体还是有问题,你可以跳过glibc的封装,直接通过syscall函数调用内核提供的SCHED_DEADLINE接口。这种方式完全不依赖glibc的版本,只需要内核支持即可:
#define _GNU_SOURCE #include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sched.h> #include <stdint.h> #include <sys/syscall.h> #include <unistd.h> #include <errno.h> // 定义SCHED_DEADLINE常量 #ifndef SCHED_DEADLINE #define SCHED_DEADLINE 6 #endif // 定义sched_attr结构体 struct sched_attr { uint32_t size; uint32_t sched_policy; uint64_t sched_flags; int32_t sched_nice; uint32_t sched_priority; uint64_t sched_runtime; uint64_t sched_deadline; uint64_t sched_period; }; int main(int argc, char *argv[]) { struct sched_attr attr = { .size = sizeof(struct sched_attr), .sched_policy = SCHED_DEADLINE, .sched_runtime = 1000000, // 1毫秒(纳秒为单位) .sched_deadline = 5000000, // 5毫秒 .sched_period = 10000000, // 10毫秒 .sched_flags = 0, .sched_nice = 0, .sched_priority = 0 }; // 调用系统设置调度属性,pid=0表示当前进程 int ret = syscall(__NR_sched_setattr, 0, &attr, 0); if (ret == -1) { perror("Failed to set SCHED_DEADLINE policy"); exit(EXIT_FAILURE); } printf("Successfully switched to SCHED_DEADLINE scheduler\n"); // 你的测试逻辑... return 0; }
编译命令同样是gcc -o deadline_test deadline_test.c,运行时需要root权限(实时调度器需要特权),所以执行时用:
sudo ./deadline_test
注意事项
- 运行SCHED_DEADLINE调度的程序必须以root权限执行,否则会因权限不足报错。
- 不要轻易尝试升级Ubuntu 16.04的glibc到新版本,这可能会导致系统依赖崩溃,优先用上面两种方法。
内容的提问来源于stack exchange,提问作者Pringles
相关产品推荐
相关产品推荐

