我有一个类似守护进程的应用程序,它在初始化时执行一些磁盘密集型处理。为了避免拖慢其他任务,我在 Windows 上做了类似的事情:
SetPriorityClass(GetCurrentProcess(), PROCESS_MODE_BACKGROUND_BEGIN);
// initialization tasks
SetPriorityClass(GetCurrentProcess(), PROCESS_MODE_BACKGROUND_END);
// daemon is ready and running at normal priority
AFAIK,在 Unices 上,我可以调用 nice 或 setpriority 并降低进程优先级,但我无法将其提高到进程创建时的状态(即,没有等同于第二次 SetPriorityClass 调用),除非我拥有 super 用户权限。有没有机会做我想念的另一种方式? (我知道我可以创建一个以低优先级运行的初始化线程并等待它在主线程上完成,但我宁愿避免它)
编辑:等效的 SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);
和 SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);
最佳答案
您说过您的处理是磁盘密集型的,因此使用 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);
}
完整示例源,see here .
根据权限,您进入后台模式是 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));
请注意,您可能无权恢复到原来的 io 优先级,因此您需要恢复到另一个尽力而为的值。
关于linux - Linux 上的 SetPriorityClass 等价物,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5692507/