4

我想让一个进程在新的 Linux SCHED_DEADLINE调度策略下调度。同时,这个进程还要创建一些工作线程来做一些其他的工作。但是,当我在成功调用sched_setattr(即设置进程调度策略)后调用pthread_create时,我得到了一个EAGAIN。我知道在实时进程中创建线程可能有点奇怪。可能会出现“新线程的调度策略是什么”等问题。

尽管如此,有没有办法在 SCHED_DEADLINE 进程中创建一个新线程?

以及如何定义新线程的调度策略?

重现我的问题的代码可以在

https://github.com/lookflying/pthread_deadline/

4

2 回答 2

2

在合并 SCHED_DEADLINE 时,内核社区在列表中明确讨论了这个话题,并决定不允许 SCHED_DEADLINE 任务创建其他任务(byfork()或 by 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()");
}
于 2018-03-29T10:04:00.503 回答
0

我想你会发现新 pthread 的默认调度策略是PTHREAD_INHERIT_SCHED. 要覆盖它,您需要一组显式的属性,用和pthread_attr_init()futz ,然后将这些属性应用到.pthread_attr_setschedpolicy()pthread_attr_setschedparam()pthread_create()

您可以在将进程设置为sched_getscheduler()并将其输入 pthread_attr 以供以后使用之前。sched_getparam()SCHED_DEADLINE

于 2014-07-10T12:23:33.057 回答