我有一个类似守护进程的应用程序,它在初始化时进行一些磁盘密集型处理。为了避免减慢其他任务的速度,我在 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 并降低进程优先级,但除非我拥有 super 用户权限,否则我无法将其提高到进程创建时的状态(即没有等效于第二次 SetPriorityClass 调用)。有没有可能是我错过的另一种方式? (我知道我可以创建一个以低优先级运行的初始化线程并等待它在主线程上完成,但我宁愿避免它)

编辑:等效 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/

10-11 19:14