具有实时优先级的pthreads

时间:2010-07-08 18:35:15

标签: c pthreads real-time scheduling

我需要管理具有不同优先级的线程池,因此我编写了以下线程启动过程:

static
int startup(thrd_t *thrd, thrd_sync_t *sync, int prio)
{
    pthread_attr_t attr;
    int err;
    struct sched_param param = {
        .sched_priority = prio
    };

    assert(pthread_attr_init(&attr) == 0);
    assert(pthread_attr_setschedpolicy(&attr, SCHED_FIFO) == 0);
    assert(pthread_attr_setschedparam(&attr, &param) == 0);
    err = pthread_create(&thrd->handler, &attr, thread_routine, (void *)thrd);
    pthread_attr_destroy(&attr);

    return err;
}

原则上,不应允许非特权用户执行此代码:pthread_create()调用应返回EPERM,因为运行具有高优先级的线程会带来安全隐患。

出乎意料的是,它适用于普通用户,但它根本不尊重给定的优先级。

我尝试通过删除pthread_attr_t并在创建线程后设置调度属性来修改代码:

static
int startup(thrd_t *thrd, thrd_sync_t *sync, int prio)
{
    pthread_attr_t attr;
    int err;
    struct sched_param param = {
        .sched_priority = prio
    };

    err = pthread_create(&thrd->handler, NULL /*&attr*/, thread_routine,
                         (void *)thrd);
    if (err != 0) return err;

    err = pthread_setschedparam(thrd->handler, SCHED_FIFO, &param);
    if (err != 0) return err;

    return err;
}

顺便说一下,这种方法管理起来要困难得多,因为如果出现错误,我需要终止新创建的线程。至少它似乎在权限要求方面正常工作(只有root可以执行此操作),但仍然没有遵守优先级。

我做错了吗?

修改

我刚刚添加了以下代码,由每个线程执行:

static
void getinfo ()
{
    struct sched_param param;
    int policy;

    sched_getparam(0, &param);
    DEBUG_FMT("Priority of this process: %d", param.sched_priority);

    pthread_getschedparam(pthread_self(), &policy, &param);

    DEBUG_FMT("Priority of the thread: %d, current policy is: %d and should be %d",
              param.sched_priority, policy, SCHED_FIFO);
}

使用第一种方法(即pthread_attr_t方法),结果是pthread_attr_setschedpolicy完全无效,因为优先级为0且策略不是SCHED_FIFO。

使用第二种方法(即pthread_setschedparam方法),该函数打印预期的数据,但执行仍然以错误的方式运行。

1 个答案:

答案 0 :(得分:8)

我认为您还必须使用pthread_attr_setinheritsched来确保您对优先级设置的更改得到考虑。从手册页:

  

PTHREAD_INHERIT_SCHED       指定调度策略和关联的属性   从创造中继承   线程和调度属性   在这个attr论证中   忽略。

     

PTHREAD_EXPLICIT_SCHED       指定调度策略和关联的属性   要设置为相应的值   来自这个属性对象。

在手册页中,您有以下内容:

  

新的inherit-scheduler属性的默认设置          初始化的线程属性对象是PTHREAD_INHERIT_SCHED。