我需要管理一个具有不同优先级的线程池,因此我编写了以下线程启动过程:
原则上,非特权用户不应该被允许执行此代码:由于使用高优先级运行线程的安全隐患,pthread_create()调用应返回EPERM。
出乎意料的是,普通用户可以正常工作,但根本不尊重给定的优先级。
我试图通过删除pthread_attr_t并在创建线程后设置调度属性来修改代码:
顺便说一下,这种方法更难管理,因为如果出现错误,我需要杀死新创建的线程。至少在权限要求方面似乎可以正常工作(只有root可以执行此操作),但仍然不尊重优先级。
我做错了什么吗?
编辑
我刚刚添加了以下代码片段,每个线程都会执行:
使用第一种方法(即
使用第二种方法(即
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, ¶m) == 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, ¶m);
if (err != 0) return err;
return err;
}
顺便说一下,这种方法更难管理,因为如果出现错误,我需要杀死新创建的线程。至少在权限要求方面似乎可以正常工作(只有root可以执行此操作),但仍然不尊重优先级。
我做错了什么吗?
编辑
我刚刚添加了以下代码片段,每个线程都会执行:
static
void getinfo ()
{
struct sched_param param;
int policy;
sched_getparam(0, ¶m);
DEBUG_FMT("Priority of this process: %d", param.sched_priority);
pthread_getschedparam(pthread_self(), &policy, ¶m);
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
方法),函数输出了预期数据,但执行结果仍然错误。
NDEBUG
,则assert(x)
是一个空操作。 - bstpierre