Search code examples
pythonmacosnice

Why would os.nice(10) fail on OS X?


Why would os.nice(10) fail with OSError: [Errno 1] Operation not permitted on OS X? Running from a standard user account:

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

Details:

  • Python 2.7.2
  • OS X 10.8.4

Solution

  • As pointed out by Lukas Graf, os.nice increments the nice level, rather than setting it.

    This appears to instead be an OS X bug, which is triggered if you call nice while sitting at a nice priority of 20 or higher:

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

    fails, while

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

    works. A simple C program exhibits the same problem:

    #include <unistd.h>
    #include <string.h>
    
    int main() {
        if(nice(10) < 0)
            perror("nice");
    }
    

    prints an error if you run it as nice -n 20 ./test, but succeeds if it is run as nice -n 19 ./test.


    The reason is because a nice level of 20 is above the maximum nice level supported by the nice API (NZERO). OS X's nice utility uses setpriority so it ignores the limit, but the nice C function (which is used directly by Python) does care. If the process priority is 20 or above, nice will attempt to set the priority to 19 which is not allowed (since it would increase the process priority, which only a privileged user can do).

    This is a weird bug, but it can easily be avoided by never using a process priority of 20.