授予进程/线程降低其自身良好值的权利的最佳方法是什么,而不以完全特权运行它?解决方案可以在过程本身之外(ulimit
或setcap
例如)。
我正在寻找至少在现代 Linux 和 Mac OS X 上可移植的东西(这就是我没有用ulimit
or回复自己的原因setcap
)。
授予进程/线程降低其自身良好值的权利的最佳方法是什么,而不以完全特权运行它?解决方案可以在过程本身之外(ulimit
或setcap
例如)。
我正在寻找至少在现代 Linux 和 Mac OS X 上可移植的东西(这就是我没有用ulimit
or回复自己的原因setcap
)。
任何进程都可以使用setpriority()
or使自己变得更好sched_setscheduler()
,任何线程都可以使用pthread_setchedparam()
and pthread_setschedprio()
。两者都在 POSIX.1-2001 中定义,因此基本上所有非 Windows 系统都应该可用。有关可用的调度程序类型和优先级的详细信息,请参阅 man 2 sched_setscheduler。
请注意,较高的数值优先级值表示更好的进程;较低的逻辑优先级。值越大,获得的 CPU 时间越少。要找出给定调度策略的最小值和最大值,您必须使用sched_get_priority_min()
和sched_get_priority_max()
。
通常,进程或线程应该始终能够降低其优先级(使其更好),并使用任何不会使其变得不那么好的调度策略。但是,2.6.12 之前的 Linux 内核不允许普通用户使用,因此您的程序可能应该尝试使其或它的某些线程更好,但如果碰巧在某些稀有架构上不允许这样做,请不要太介意. 最重要的是,你的算法设计不应该依赖于调度;争取比这更健壮的代码。
您需要额外的权限来降低 nice 值(增加逻辑优先级)。在 Linux 中,这意味着要么由 root 运行,要么具有 CAP_SYS_NICE 功能。两者都可以为二进制可执行文件设置(通过 chown 和 chmod 的 setuid root 或 setcap)。前者适用于所有类 Unix 系统(但安装时需要 root 权限),但后者是特定于 Linux 的。
最可接受的可移植方式可能是编写一个可以安装 setuid root 的包装程序。这将非常简单,只需几十行 C。它只需调用 sched_get_priority_min()、sched_get_priority_max()、sched_setscheduler() 和 sched_setparam() 来降低 nice 值(获得更多 CPU 时间),然后调用 seteuid (0); setregid(getgid(), getgid); setreuid(getuid(), getuid()); 删除额外的权限,最后 execv() 实际程序。注意:您绝对希望在安装时硬编码实际程序的路径。这应该在所有 Linux 和类 Unix 系统上无需修改即可工作。
在您的实际程序中,您只需增加不太重要的线程的友好度。换句话说,您不要试图降低程序中任何线程的友好度,而是增加所有其他线程的友好度。setuid 根包装程序是降低最低友好度级别的可移植方式。您显然可以先检查当前的 niceness 和 scheduler 详细信息,看看是否有足够的范围进行调整。也许你的包装程序可以设置命令行参数或环境变量来告诉实际程序使用哪个优先级。