我想在新的Linux SCHED_DEADLINE 调度策略下安排一个流程。同时,这个过程必须创建一些工作线程做其他一些工作。但是,在成功调用 sched_setattr (即设置进程调度策略)后,当我调用 pthread_create 时,我得到了 EAGAIN 。 我知道在实时进程中创建一个线程可能有点奇怪。一些问题,例如"新线程的调度策略将是什么"可能会出现。
尽管如此,有没有办法在SCHED_DEADLINE流程中创建新线程?
如何定义新线程的调度策略?
可以在
找到重现我的问题的代码答案 0 :(得分:0)
我认为您会发现新pthread的默认调度策略是PTHREAD_INHERIT_SCHED
。要覆盖此属性,您需要pthread_attr_init()
一组明确的属性,使用pthread_attr_setschedpolicy()
和pthread_attr_setschedparam()
进行评估,然后在pthread_create()
中应用这些属性。
在将流程设置为sched_getscheduler()
之前,您可以sched_getparam()
和SCHED_DEADLINE
将这些流程提供给pthread_attr以供日后使用。
答案 1 :(得分:0)
合并SCHED_DEADLINE时,内核社区在列表中明确讨论了此主题,并决定不允许SCHED_DEADLINE任务创建其他任务(fork()
或pthread_create()
)。
因此,目前,没有办法实现这种行为。您必须在设置SCHED_DEADLINE优先级之前创建任务。
关于第二个问题,遗憾的是glibc尚未包装sched_setattr()系统调用(尽管4年后可用)。以下是一些用于创建SCHED_DEADLINE任务的代码:
#define _GNU_SOURCE
#include <linux/kernel.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <time.h>
#include <linux/types.h>
#include <sched.h>
#include <linux/sched.h>
#include <sys/types.h>
#define SCHED_DEADLINE 6
/* __NR_sched_setattr number */
#ifndef __NR_sched_setattr
#ifdef __x86_64__
#define __NR_sched_setattr 314
#endif
#ifdef __i386__
#define __NR_sched_setattr 351
#endif
#ifdef __arm__
#define __NR_sched_setattr 380
#endif
#ifdef __aarch64__
#define __NR_sched_setattr 274
#endif
#endif
/* __NR_sched_getattr number */
#ifndef __NR_sched_getattr
#ifdef __x86_64__
#define __NR_sched_getattr 315
#endif
#ifdef __i386__
#define __NR_sched_getattr 352
#endif
#ifdef __arm__
#define __NR_sched_getattr 381
#endif
#ifdef __aarch64__
#define __NR_sched_getattr 275
#endif
#endif
struct sched_attr {
__u32 size;
__u32 sched_policy;
__u64 sched_flags;
/* SCHED_NORMAL, SCHED_BATCH */
__s32 sched_nice;
/* SCHED_FIFO, SCHED_RR */
__u32 sched_priority;
/* SCHED_DEADLINE */
__u64 sched_runtime;
__u64 sched_deadline;
__u64 sched_period;
};
int sched_setattr(pid_t pid,
const struct sched_attr *attr,
unsigned int flags)
{
return syscall(__NR_sched_setattr, pid, attr, flags);
}
int sched_getattr(pid_t pid,
struct sched_attr *attr,
unsigned int size,
unsigned int flags)
{
return syscall(__NR_sched_getattr, pid, attr, size, flags);
}
然后,在任务代码中:
struct sched_attr attr;
attr.size = sizeof(attr);
attr.sched_flags = 0;
attr.sched_nice = 0;
attr.sched_priority = 0;
/* This creates a 10ms/30ms reservation */
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = 10 * 1000 * 1000;
attr.sched_period = attr.sched_deadline = 30 * 1000 * 1000;
if (sched_setattr(0, &attr, flags) < 0) {
perror("sched_setattr()");
}