为啥 os.nice(10) 在 OS X 上会失败?

Posted

技术标签:

【中文标题】为啥 os.nice(10) 在 OS X 上会失败?【英文标题】:Why would os.nice(10) fail on OS X?为什么 os.nice(10) 在 OS X 上会失败? 【发布时间】:2014-09-10 19:21:16 【问题描述】:

为什么os.nice(10) 在 OS X 上会因OSError: [Errno 1] Operation not permitted 而失败?从标准用户帐户运行:

$ python
…
>>> os.nice(10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 1] Operation not permitted

详情:

Python 2.7.2 OS X 10.8.4

【问题讨论】:

也许该进程已经以更高的 nice 级别运行。检查ps 以查看您的进程运行的nice 级别。 啊,就是这样!几天前我忘记了我会在航站楼下车,并没有意识到超过 20 岁是一个错误。 【参考方案1】:

正如 Lukas Graf 所指出的,os.nice 会增加 nice 级别,而不是设置它。

这似乎是一个 OS X 错误,如果您在优先级为 20 或更高的情况下调用nice,则会触发该错误:

nice -n 20 python -c 'import os; os.nice(10)'

失败,而

nice -n 19 python -c 'import os; os.nice(10)'

有效。一个简单的 C 程序也会出现同样的问题:

#include <unistd.h>
#include <string.h>

int main() 
    if(nice(10) < 0)
        perror("nice");

如果您以nice -n 20 ./test 运行它会打印一个错误,但如果它以nice -n 19 ./test 运行则会成功。


原因是因为 nice 级别 20 高于 nice API (NZERO) 支持的最大 nice 级别。 OS X 的nice 实用程序使用setpriority,因此它忽略了限制,但nice C 函数(由Python 直接使用)确实很在意。如果进程优先级为 20 或更高,nice 将尝试将优先级设置为 19,这是不允许的(因为它会增加进程优先级,只有特权用户可以这样做)。

这是一个奇怪的错误,但可以通过从不使用 20 的进程优先级来轻松避免。

【讨论】:

Err,忽略前面的评论。 Python 的行为是正确的。超过 20 岁只是一个错误。 @nneonneo 抱歉,我删除了我的评论,因为在写完之后,我观察到的行为似乎与它相矛盾:我的 python 从不错的 0 开始,我可以反复调用 os.nice(10),它永远不会出错,总是以相对数量递增,并且上限为19。但是,单个 os.nice(-1) 始终会导致 Operation not permitted,而不管任何先决条件。 @LukasGraf:是的,那是因为os.nice(-1) 要求“增量”为 -1,根据定义,这会降低友好度。 @nneonneo 是的,但我不应该被允许为自己的流程这样做吗? (我不完全记得你的评论,但我记得它指出os.nice 是一个增量,我完全忽略了一个细节。)【参考方案2】:

检查您的 PRIO_MAX 是什么以及允许非超级用户使用哪些好处

超级用户以外的用户只能改变他们拥有的进程的优先级,并且只能在 0 到 PRIO_MAX (20) 的范围内单调地单调地增加他们的“好值”。

https://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man8/renice.8.html

【讨论】:

以上是关于为啥 os.nice(10) 在 OS X 上会失败?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Core Data SQLite 存储不能从 OS X 10.8 向后兼容到 10.4?

迭代时修改list和dictionary,为啥在dict上会失败?

为啥在Windows XP上用VMware 9装Mac OS X 10.7,装好了却说“客户机操作系统不支持Mac OS X服务器”。

为啥 apt-get 功能在 Mac OS X v10.9 (Mavericks) 的终端中不起作用?

Core Data Macos 应用程序和与 OS X 10.7 的兼容性

为啥我的 Javascript 在 iOS 上会中断?