Linux上的SetPriorityClass等效项

Linux上的SetPriorityClass等效项,linux,unix,process,Linux,Unix,Process,我有一个类似守护进程的应用程序,它在初始化时执行一些磁盘密集型处理。为了避免减慢其他任务的速度,我在Windows上执行以下操作: SetPriorityClass(GetCurrentProcess(), PROCESS_MODE_BACKGROUND_BEGIN); // initialization tasks SetPriorityClass(GetCurrentProcess(), PROCESS_MODE_BACKGROUND_END); // daemon is ready

我有一个类似守护进程的应用程序,它在初始化时执行一些磁盘密集型处理。为了避免减慢其他任务的速度,我在Windows上执行以下操作:

SetPriorityClass(GetCurrentProcess(), PROCESS_MODE_BACKGROUND_BEGIN);

// initialization tasks

SetPriorityClass(GetCurrentProcess(), PROCESS_MODE_BACKGROUND_END);

// daemon is ready and running at normal priority
好吧,在Unices上,我可以调用nice或setpriority并降低进程优先级,但除非我拥有超级用户权限,否则我无法将其提高回进程创建时的优先级(即,没有与第二次SetPriorityClass调用等效的优先级)。有没有我错过的另一种方法?(我知道我可以创建一个低优先级运行的初始化线程,并等待它在主线程上完成,但我更愿意避免它)


编辑:等效
SetThreadPriority(GetCurrentThread(),线程模式\u后台\u开始)的加分
设置线程优先级(GetCurrentThread(),线程模式\u后台\u结束)

事实上,如果您有一个相当新的Linux内核,可能会有一个解决方案。TLPI是这么说的:

在2.6.12之前的Linux内核中 非特权进程可以使用 将优先级()仅设置为(不可逆) 降低其自身或其他进程的 价值不错

自内核2.6.12以来,Linux提供 RLIMIT_NICE资源限制 允许非特权流程 增加好的值。无特权的人 流程可以提高自身的价值 达到指定的最大值 公式20–rlim_cur,其中rlim_cur 当前的RLIMIT_很软吗 资源限制

所以基本上你必须:

  • 使用设置RLIMIT\U NICE
  • 像往常一样使用
  • 这里有一个例子

    编辑
    /etc/security/limits.conf
    。加

    cnicutar    -    nice    -10
    
    使用ulimit验证

    cnicutar@aiur:~$ ulimit -e
    30
    
    我们喜欢这个限制,所以我们不会改变它

    漂亮的ls

    cnicutar@aiur:~$ nice -n -10 ls tmp
    cnicutar@aiur:~$ 
    
    cnicutar@aiur:~$ nice -n -11 ls tmp
    nice: cannot set niceness: Permission denied
    
    设置优先级
    示例

    #include <stdio.h>
    #include <sys/resource.h>
    #include <unistd.h>
    
    int main()
    {
            int rc;
    
            printf("We are being nice!\n");
            /* set our nice to 10 */
            rc = setpriority(PRIO_PROCESS, 0, 10);
            if (0 != rc) {
                    perror("setpriority");
            }
    
            sleep(1);
    
            printf("Stop being nice\n");
            /* set our nice to -10 */
            rc = setpriority(PRIO_PROCESS, 0, -10);
            if (0 != rc) {
                    perror("setpriority");
            }
    
            return 0;
    }
    

    唯一的缺点是它不能移植到其他Unix(或者它是Unixes?)。

    要解决降低优先级然后将其恢复的问题,您可以:

  • fork()
  • 儿童:降低其优先级
  • 父级:等待子级(保留原始父级的优先级)
  • 孩子:完成工作(优先级较低)
  • 父项:完成子项后,继续使用原始优先级

  • 这应该是UNIX可移植解决方案。

    您说过您的处理是磁盘密集型的,所以使用
    nice
    的解决方案不起作用<代码>尼斯
    处理CPU访问的优先级,而不是I/O访问<代码>进程\模式\后台\开始
    降低了I/O优先级和CPU优先级,并且需要XP和更早版本中不存在的内核功能

    控制I/O优先级不能跨Unice移植,但在现代Linux内核上有一个解决方案。您需要
    CAP_SYS_ADMIN
    将I/O优先级降低到
    IO_PRIO_CLASS_IDLE
    ,但在没有此选项的情况下,可以降低和提高best effort类的优先级

    关键函数调用是,您必须通过
    syscall
    包装器调用:

    static int ioprio_set(int which, int who, int ioprio)
    {
        return syscall(SYS_ioprio_set, which, who, ioprio);
    }
    
    有关完整示例源

    根据权限的不同,进入后台模式的值可以是
    IOPRIO\u PRIO\u值(IO\u PRIO\u CLASS\u IDLE,0)
    IOPRIO\u PRIO\u值(IO\u CLASS\u BE,7)
    。然后,顺序应为:

    #define IOPRIO_PRIO_VALUE(class, data)  (((class) << IOPRIO_CLASS_SHIFT) | data)
    
    ioprio_set(IOPRIO_WHO_PROCESS, 0, IOPRIO_PRIO_VALUE(IO_PRIO_CLASS_BE,7));
    // Do work
    ioprio_set(IOPRIO_WHO_PROCESS, 0, IOPRIO_PRIO_VALUE(IO_PRIO_CLASS_BE,4));
    
    #定义IOPRIO_PRIO_值(类,数据)((类)来自以下问题:“(我知道我可以创建一个低优先级运行的初始化线程,并等待它在主线程上完成,但我宁愿避免它)”
    
    #define IOPRIO_PRIO_VALUE(class, data)  (((class) << IOPRIO_CLASS_SHIFT) | data)
    
    ioprio_set(IOPRIO_WHO_PROCESS, 0, IOPRIO_PRIO_VALUE(IO_PRIO_CLASS_BE,7));
    // Do work
    ioprio_set(IOPRIO_WHO_PROCESS, 0, IOPRIO_PRIO_VALUE(IO_PRIO_CLASS_BE,4));