c - CentOS8实时FIFO进程未收到XCPU信号
问题描述
背景
我有一个非常精确的计划,我需要为此使用实时调度策略。该程序应该做什么是不可能的。不过,在编写实际程序之前,我想测试一些东西——实时和“正常”调度策略之间的一些差异(例如,我注意到 nanosleep 的实时 FIFO 精度提高了 10 倍调度和 99 优先级),当然还有 SIGXCPU 信号,如果它一次超过软允许的 CPU 时间,则应该将其发送到实时进程。尽管我的进程正在无限循环地消耗 CPU 时间,但我没有收到它。
环境
我正在使用托管在 vultr 上的 CentOS8 - 1 个核心、512MB RAM、最新版本的内核和每个软件包。没有我的实时进程运行,top
显示 2-3 个进程正在运行(systemd
是主要进程)和 80 多个睡眠。活动进程似乎都有正常的调度策略,优先级设置为 20,这是最低的。
我的实时进程的代码如下所示:
#define _GNU_SOURCE
// most of these are useless yes, were used before for testing
// and I just did not care to remove them, but that shouldn't change anything, right
#include <sched.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdatomic.h>
#include <signal.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
static uint64_t GetTimeoutTime(const uint64_t nanoseconds) {
struct timespec tp = { .tv_sec = 0, .tv_nsec = 0 };
(void) clock_gettime(CLOCK_MONOTONIC, &tp);
return (uint64_t)(tp.tv_sec) * 1000000000 + (uint64_t)(nanoseconds / 1000000000) * 1000000000 + (uint64_t)(tp.tv_nsec) + nanoseconds - (uint64_t)(nanoseconds / 1000000000) * 1000000000;
}
static int siga(int signum, void (*handler)(int)) {
return sigaction(signum, &((struct sigaction){ .sa_handler = handler, .sa_flags = 0, .sa_mask = 0 }), NULL);
}
static void xcpu(int sig) {
puts("xcpu called");
(void) pthread_yield(); // to not get killed
}
int main() {
uint64_t g = 0;
uint64_t t1, t2;
int err = siga(SIGXCPU, xcpu);
if(err != 0) {
puts("e");
printf("%d\n", err);
}
if(sched_setscheduler(getpid(), SCHED_FIFO, &((struct sched_param){ .sched_priority = 99 })) != 0) {
puts("err");
}
while(1) {
t1 = GetTimeoutTime(0); // just some stuff to make the process busy
t2 = GetTimeoutTime(0) - t1; // I was using this code before, thus left it there
g += t2;
}
printf("avg %lf\n", (double)(g) / 10000.0); // just to make it seem as g is not useless
return 0;
}
结果是 - 进程不断占用 90% 以上的 CPU,运行和运行,并且看不到接收到任何信号。我实际上让程序运行了大约 15 分钟,但什么也没发生 - 进程没有被杀死。我的意思是,FIFO调度不应该在线程运行时删除它们,对吗?这就是 Round Robin 所做的,所以我不太明白是什么导致了这种现象。我的线程是否在我不知情的情况下进入睡眠状态?
将截止时间设置为某个 2^63 - (1, 2, 3) 数字的 DEADLINE 调度会比当前的 FIFO 解决方案更好吗?我只是想在大多数时候为自己获得大部分 CPU,因为实际上除了我自己的进程将使用 CPU(唯一的区别是实时调度策略提供了一些好处,其中之一)我在开始时注意到并描述了 - 提高 nanosleep 的精度。还有其他好处吗?)。
解决方案
好吧,我找到了答案。
问题在于 RTIME 软硬限制。我认为默认情况下它们非常低,但现在我仔细检查以确定。软限制和硬限制都是 2^63 个数字。在将软限制降低到 1e6 和硬限制到 1e7 后,我的进程开始每秒接收 XCPU 信号。getrlimit
使用and函数检查和降低setrlimit
(有关更多信息,请参阅 man )。
推荐阅读
- gnuradio - 同步 USRP 源块 - 多个 B2xx 设备
- javascript - 按键检索 Prismic 数据的问题
- python - LearningShapelet with variable-length time-series returns nan in predictions array
- reactjs - How fill in input box on page Load in React?
- symfony4 - EasyAdmin 3 : Nested forms
- javascript - Configure ESLint to parse .ts and .tsx as Typescript and .js and .jsx as Ecmascript
- python - passing data from one class method to another class method
- r - my plotting of geom_sf has a quite strange scale
- c - Solving Time Complexity with Fibonacci
- php - 如何在 WordPress URL 结构中的自定义帖子固定链接中添加多个分类法