Linux上的SetPriorityClass等价物

CAF*_*FxX 3 unix linux process

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

SetPriorityClass(GetCurrentProcess(), PROCESS_MODE_BACKGROUND_BEGIN);

// initialization tasks

SetPriorityClass(GetCurrentProcess(), PROCESS_MODE_BACKGROUND_END);

// daemon is ready and running at normal priority
Run Code Online (Sandbox Code Playgroud)

AFAIK,在Unices上我可以调用nice或setpriority并降低进程优先级但我无法将其恢复到创建进程时的状态(即没有相当于第二个SetPriorityClass调用),除非我有超级用户权限.难道有另外一种方法可以让我失踪吗?(我知道我可以创建一个以低优先级运行的初始化线程,并等待它在主线程上完成,但我宁愿避免它)

编辑:等效SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);和的奖励积分SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);

Adr*_*Cox 5

您已经说过,您的处理是磁盘密集型的,因此使用的解决方案nice将无效. nice处理CPU访问的优先级,而不是I/O访问.PROCESS_MODE_BACKGROUND_BEGIN降低I/O优先级以及CPU优先级,并且需要XP和更早版本中不存在的内核功能.

控制I/O优先级不能在Unices中移植,但现代Linux内核上有一个解决方案.您需要CAP_SYS_ADMIN降低I/O优先级IO_PRIO_CLASS_IDLE,但如果没有这个优先级,可以在尽力而为的类中降低和提高优先级.

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

static int ioprio_set(int which, int who, int ioprio)
{
    return syscall(SYS_ioprio_set, which, who, ioprio);
}
Run Code Online (Sandbox Code Playgroud)

有关完整示例源,请参见此处.

根据权限,您进入后台模式是IOPRIO_PRIO_VALUE(IO_PRIO_CLASS_IDLE,0)IOPRIO_PRIO_VALUE(IO_PRIO_CLASS_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));
Run Code Online (Sandbox Code Playgroud)

请注意,您许多人无权返回原始io优先级,因此您需要返回另一个尽力而为值.