我尝试以根用户身份在Linux系统上使用SCHED_FIFO或SCHED_RR策略生成线程,但对pthread_create()的调用返回1(EPERM)。pthread_create()的手册页上说EPERM指示“调用者没有适当的权限来设置所需的调度参数或调度策略”。root不应该能够指定SCHED_FIFO或SCHED_RR吗?
我已经将创建线程的代码剥离到一个小程序中,该程序仅执行此操作。它看起来对我来说是正确的,但仍然得到错误。我做错了什么?
该方案:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
static void *_Thread(void *arg)
{
(void)arg;
printf("Thread running!\n");
return NULL;
}
int main(void)
{
int retVal;
pthread_attr_t attr;
struct sched_param schedParam;
pthread_t thread;
retVal = pthread_attr_init(&attr);
if (retVal)
{
fprintf(stderr, "pthread_attr_init error %d\n", retVal);
exit(1);
}
retVal = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
if (retVal)
{
fprintf(stderr, "pthread_attr_setinheritsched error %d\n", retVal);
exit(1);
}
retVal = pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
if (retVal)
{
fprintf(stderr, "pthread_attr_setschedpolicy error %d\n", retVal);
exit(1);
}
schedParam.sched_priority = 1;
retVal = pthread_attr_setschedparam(&attr, &schedParam);
if (retVal)
{
fprintf(stderr, "pthread_attr_setschedparam error %d\n", retVal);
exit(1);
}
retVal = pthread_create(&thread,
&attr,
_Thread,
NULL);
if (retVal)
{
fprintf(stderr, "pthread_create error %d\n", retVal);
exit(1);
}
retVal = pthread_join(thread, NULL);
if (retVal)
{
fprintf(stderr, "pthread_join error %d\n", retVal);
exit(1);
}
printf("main run successfully\n");
return 0;
}
此程序已编译并以root身份运行。运行时,它的程序在调用pthread_create时失败,返回EPERM。
将线程更改为SCHED_RR调度没有影响-pthread_create仍然返回EPERM。
将线程更改为SCHED_OTHER调度,并将其优先级更改为0,这样程序就可以无错误地运行。
5条答案
按热度按时间368yc8dk1#
一定是你的实时优先软限制太严格了。
在运行代码之前,在shell中调用
ulimit -r unlimited
。或者直接在代码中调用setrlimit(RLIMIT_RTPRIO, ...)
。系统范围的限制以
/etc/security/limits.conf
为单位设置。4ioopgfo2#
令人惊讶的是,我遇到了与10年后的OP相同的问题:CentOS 7.6,生成一个实时线程,root用户,ulimit -r表示“unlimited”,但线程创建失败,返回EPERM。原来是Linux内核中的以下子句导致了故障:
鉴于此,以及Linux cgroup文档https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt和CONFIG_RT_GROUP_SCHED文档https://www.kernel.org/doc/Documentation/scheduler/sched-rt-group.txt,通过将当前shell添加到现有的cgroup并提供实时调度信息,可以解决问题:
然后运行可执行文件,从当前shell生成一个实时线程,线程创建成功。
flvtvl503#
我已经在Linux(2.6内核),Solaris 9和10上测试了你的代码。没问题。这与您的实时优先级设置有关。您可以通过以下方式更改此设置:
哎呀,马克西姆已经带着答案来了。
bjp0bcyl4#
以root用户身份运行程序。因为我们正在扰乱调度(它的FIFO和RR)。你也会(含蓄地)混淆相对优先级,而这只有root才能做到。
在上面的程序正常运行时,pthread_create()返回EPERM,但作为root用户,它工作得很好。
欲了解更多信息,请访问:http://www.linuxforums.org/forum/programming-scripting/111359-pthread-error.html
5f0d552i5#
在CentOS 7上遇到了这个。在将/proc/sys/kernel/sched_rt_runtime_us设置为-1之后,它就可以工作了。