2010-07-08 132 views
6

我需要管理具有不同优先级的线程池,所以我写了下面的线程启动程序:并行线程与实时优先级

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可以执行此操作),但仍不优先考虑优先级。

我做错了什么?

EDIT

我刚加入其由每一个线程执行的下面的代码段:

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

你如何确定呼叫不被尊重?我遇到过类似的情况,但API没有实现,因此失败。 – Ioan 2010-07-08 19:56:48

+0

@Ioan:查看问题的更新版本。 – Dacav 2010-07-08 20:17:10

+1

OT:不要在'assert()'中放置代码。如果这是用断言禁用编译的,代码将不会被执行。 – bstpierre 2010-07-15 17:04:03

回答

8

我认为你也必须使用pthread_attr_setinheritsched来确保你对优先级设置的改变被考虑在内。从手册页:

PTHREAD_INHERIT_SCHED 指定调度策略和相关属性 从创建 线程继承,并调度在此ATTR参数属性 是要 忽略。

PTHREAD_EXPLICIT_SCHED 指定的调度策略和关联属性是 被设置为从该属性对象中的相应值 。

一点点手册页进一步您有:

的继承,调度的属性的默认设置在新 初始化线程属性对象PTHREAD_INHERIT_SCHED。

+0

它的工作!非常感谢:这解决了两个问题之一。然而,这很违反直觉:如果我指定优先级,可能是因为我想让你使用它,对吧? :)现在我会找到错误行为的原因:也许是一个错误? – Dacav 2010-07-08 21:39:03

+0

@Dacav:你能否详述一下你的第二个问题?不知道我得到它。该领域的错误(但你自己;-)是不太可能的。你没有多说你正在运行的系统,但是现在线程实现每天都经过了数十亿次的测试。 – 2010-07-08 21:44:52

+0

目前我的程序只是一个脚手架:真正的业务逻辑应该稍后添加。为了测试每个线程的优先级,首先通过等待一个条件变量来启动,该条件变量随后被广播。然后每个线程不断在stderr上写假。我期望的是在优先级较低的线程之前观看更高优先级的线程'虚假'。我怀疑我的双核心是出乎意料的交错的原因......我现在想着一个很好的测试。 – Dacav 2010-07-08 21:59:16