代码之家  ›  专栏  ›  技术社区  ›  Dacav

具有实时优先级的pthreads

  •  6
  • Dacav  · 技术社区  · 15 年前

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

    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;
    }
    

    顺便说一下,这种方法更难管理,因为在发生错误的情况下,我需要终止新创建的线程。至少它看起来在权限需求方面工作正常(只有根可以执行此操作),但优先级仍然不受尊重。

    我做错什么了吗?

    编辑

    我刚刚添加了以下代码,每个线程都会执行这些代码:

    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 方法)结果发现pthread-attr-setschedpolicy完全无效,因为优先级为0,而策略不是sched-fifo。

    第二种方法(即 pthread_setschedparam 方法)函数打印预期的数据,但执行的行为始终是错误的。

    1 回复  |  直到 9 年前
        1
  •  8
  •   Loufylouf    9 年前

    我想你也要用 pthread_attr_setinheritsched 以确保考虑对优先级设置所做的更改。从手册页:

    pthread_inherit_sched 指定计划策略和关联属性为 从创造中继承 线程和调度属性 在这个ATTR论证中 忽略。

    pthread_显式_sched 指定计划策略和关联属性为 设置为相应的值 从这个属性对象。

    在手册页上再进一步,您可以看到:

    在新的 初始化的线程属性对象是pthread_inherit_sched。