You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用setpriority()修改进程nice值时遇EPERM权限错误求助

问题分析与解决指导

一、核心问题根源

你的问题确实和权限限制直接相关,包括RLIMIT_NICE资源限制以及Linux能力(Capabilities),分两部分拆解:

1. setpriority 报错EPERM的原因

  • 普通用户默认仅能提高nice值(范围019,值越大优先级越低),要设置负数nice值(-20-1,优先级更高)需要突破资源限制或获得特殊权限。
  • 你之前设置rl.rlim_cur=20是错误的:RLIMIT_NICE的取值和nice值是反向映射关系,公式为 rlim_cur = 20 - nice。比如要允许设置nice=-10,需要rlim_cur=30(20 - (-10) =30),最大值40对应nice=-20。
  • sudo执行仍失败,大概率是代码未正确调整RLIMIT_NICE,或sudo环境下的资源限制未放开。

2. SCHED_RR 实时调度策略失败的原因

SCHED_RR属于实时调度策略,Linux下要求进程必须拥有CAP_SYS_NICE能力才能设置,普通用户默认无此权限,即使sudo也可能因环境限制或权限传递问题失效。


二、分步解决方法

(一)修复setpriority问题

1. 正确设置RLIMIT_NICE

修改代码,在调用setpriority前添加正确的资源限制配置:

struct rlimit rl;
// 获取当前RLIMIT_NICE限制
if (getrlimit(RLIMIT_NICE, &rl) == -1) {
    perror("getrlimit");
    exit(EXIT_FAILURE);
}
// 设置允许nice值低至-10(对应rlim_cur=30)
rl.rlim_cur = 30;
if (setrlimit(RLIMIT_NICE, &rl) == -1) {
    perror("setrlimit");
    exit(EXIT_FAILURE);
}

2. 系统层面放开限制

编辑/etc/security/limits.conf,添加以下配置(替换username为你的用户名):

username soft nice -10
username hard nice -10

保存后重新登录,系统会自动将nice值转换为对应的RLIMIT_NICE值。

3. sudo执行的注意事项

如果sudo仍失败,使用sudo -i进入root shell后再执行程序,避免环境变量或sudoers配置的权限限制影响。


(二)修复SCHED_RR设置问题

要设置实时调度策略,需获得CAP_SYS_NICE权限,两种实现方式:

1. 直接用sudo执行

确保sudo给予完整权限,执行命令:

sudo ./your_program

若仍失败,在/etc/security/limits.conf中添加实时优先级限制:

username soft rtprio 99
username hard rtprio 99

(99是SCHED_RR的最大优先级,对应sched_get_priority_max(SCHED_RR)的返回值)

2. 给程序添加CAP_SYS_NICE能力

无需每次sudo,直接给二进制文件添加永久权限:

sudo setcap cap_sys_nice+ep ./your_program

之后普通用户执行程序即可设置实时调度策略和负数nice值。


三、修改后的完整测试代码

#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>

int
main(void)
{
    int pol;
    struct sched_param sp;
    struct rlimit rl;

    // 先配置RLIMIT_NICE,允许设置nice=-10
    if (getrlimit(RLIMIT_NICE, &rl) == -1) {
        perror("getrlimit");
        exit(EXIT_FAILURE);
    }
    rl.rlim_cur = 30;
    if (setrlimit(RLIMIT_NICE, &rl) == -1) {
        perror("setrlimit");
        exit(EXIT_FAILURE);
    }

    pol = sched_getscheduler(getpid());
    if (pol == -1) {
        perror("sched_getscheduler");
        exit(EXIT_FAILURE);
    }

    if (sched_getparam(0, &sp) == -1) {
        perror("sched_getparam");
        exit(EXIT_FAILURE);
    }
            
    printf("%ld: %-5s ", (long)getpid(),
            (pol == SCHED_OTHER) ? "OTHER" :
            (pol == SCHED_RR) ? "RR" :
            (pol == SCHED_FIFO) ? "FIFO" :
#ifdef SCHED_BATCH              /* Linux-specific */
            (pol == SCHED_BATCH) ? "BATCH" :
#endif
#ifdef SCHED_IDLE               /* Linux-specific */
            (pol == SCHED_IDLE) ? "IDLE" :
#endif
            "???");
    printf("%2d\n", sp.sched_priority);

    if (setpriority(PRIO_PROCESS, 0, -10) == -1) {
        perror("setpriority");
        exit(EXIT_FAILURE);
    }

    printf("New Nice value is %d\n", getpriority(PRIO_PROCESS, 0));

#ifdef _POSIX_PRIORITY_SCHEDULING
        printf("Setting scheduler to real-time RR and current process priority to %d\n", sched_get_priority_max(SCHED_RR));
        sp.sched_priority=sched_get_priority_max(SCHED_RR);
        printf("sp.sched prio is %d\n", sp.sched_priority);
        if (sched_setscheduler(getpid(), SCHED_RR, &sp) == -1) {
            perror("sched_setscheduler");
            exit(EXIT_FAILURE);
        }
#endif   
    return 0;
}

四、验证步骤

  1. 编译代码:gcc -o nice_test nice_test.c
  2. 普通用户测试:先配置limits.conf并重新登录,或给程序添加CAP_SYS_NICE能力,执行./nice_test
  3. sudo测试:sudo ./nice_test

内容的提问来源于stack exchange,提问作者Πέτρος Λάμψας

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 05:43:11