linux用nice/setpriority调进程优先级,普通用户只能调低(值变大),-20最高、+19最低;windows用setpriorityclass设进程类,需getcurrentprocess()伪句柄且不可closehandle;跨平台应分设nice和优先级类接口,不掩盖语义差异。

Linux下用nice和setpriority改进程优先级,别碰renice子进程
Linux没有全局“提升进程优先级”的魔法开关,nice值只影响调度器对当前进程的CPU时间分配倾向,且普通用户只能调低(数值变大),不能调高。真正生效的是setpriority(PRIO_PROCESS, 0, nice_value)——第二个参数传0表示当前进程,别传getpid()以为更安全,其实一样,但传错PID会导致静默失败。
常见错误:启动子进程后,在父进程中对子PID调setpriority,但子进程已进入exec阶段,调度策略可能被重置;更稳妥的做法是在fork后、exec前,在子进程中自己调一次setpriority。
-
nice值范围是−20(最高)到+19(最低),但非root用户无法设低于0的值 - 实时调度(
SCHED_FIFO/SCHED_RR)需sudo或CAP_SYS_NICE能力,setpriority不控制这个,得用sched_setscheduler - 同一cgroup下,
nice差异的影响会被cgroup CPU quota削弱,别在容器里指望它大幅抢资源
Windows上SetPriorityClass必须配GetCurrentProcess,不能硬写句柄
Windows的优先级是进程级的“类”(如BELOW_NORMAL_PRIORITY_CLASS),不是数值,SetPriorityClass第一个参数必须是有效进程句柄,而GetCurrentProcess()返回的是伪句柄(值为−1),它能在所有API中直接使用,比用OpenProcess拿句柄更轻量、无权限风险。
常见错误:有人把GetCurrentProcess()结果存成HANDLE变量后,又去CloseHandle——这是非法操作,会触发未定义行为;伪句柄不需要也不允许关闭。
立即学习“C++免费学习笔记(深入)”;
- 设置
HIGH_PRIORITY_CLASS不会让进程突破系统保护,I/O优先级仍受SetThreadPriority单独控制 - 服务进程默认运行在
NORMAL_PRIORITY_CLASS,即使你显式设一次,后续被SCM(Service Control Manager)拉起时可能重置 - UWP或沙盒应用无法调用
SetPriorityClass,会直接返回FALSE,GetLastError()通常是ERROR_ACCESS_DENIED
C++跨平台封装要分清“请求”和“实际生效”,别假设调用成功就真变了
Linux和Windows对优先级的解释根本不同:Linux的nice是相对调度权重,Windows的优先级类是抢占式调度门槛建议。封装函数返回true只代表系统API调用没出错,不代表进程真的拿到了更多CPU时间——尤其在负载高、有其他实时线程或cgroup限制时。
实操建议:封装层不要隐藏平台差异,比如用一个set_process_priority(int level)接口,level映射到不同平台语义,反而容易误导。更可靠的是暴露两套明确命名的函数:set_process_nice(int value)和set_process_priority_class(PriorityClass cls),让调用者清楚自己在动哪根弦。
- Linux下
setpriority失败时返回−1,errno可能是EACCES(权限不足)或EINVAL(值越界),别只看return值 - Windows下
SetPriorityClass失败时返回FALSE,必须立刻查GetLastError(),常见是ERROR_INVALID_HANDLE(传了无效句柄)或ERROR_ACCESS_DENIED - macOS不支持
nice对整个进程生效(仅线程),要用task_policy_set,但需要TASK_POLICY_ENABLEentitlement,普通App Store应用拿不到
别在多线程程序里只设主线程优先级,线程调度和进程优先级不是一回事
进程优先级(Linux nice/Windows 类)影响的是该进程所有线程的**基础调度权重**,但它不替代线程级控制。比如你在Windows上设了HIGH_PRIORITY_CLASS,但某个关键计算线程仍用默认THREAD_PRIORITY_NORMAL,那它在同进程内仍可能被其他设了THREAD_PRIORITY_ABOVE_NORMAL的线程压制。
所以跨平台封装如果只提供“进程优先级”接口,对真实场景帮助有限。高频计算任务应配合线程级调整:Linux用pthread_setschedparam设SCHED_FIFO + 优先级,Windows用SetThreadPriority;且注意线程优先级提升同样受权限限制。
- Linux下,
fork后的子进程继承父进程nice值,但exec后线程调度策略会重置为SCHED_OTHER - Windows下,新创建线程默认继承创建者线程的优先级,不是进程类;所以改完进程类后,还得主动调
SetThreadPriority(GetCurrentThread(), ...)才影响当前线程 - 调试时用
ps -o pid,ni,pri,comm(Linux)或Process Explorer(Windows)确认实际值,别信代码里的return true










