os.setsid 操作不被允许
好的,请耐心听我说,网上似乎有一些关于这个问题的答案,但我就是搞不明白。
我是在一个Django Celery环境中运行它的,经过了两次分叉。我不知道这些是否会改变什么,但我猜应该没有。
代码不多,留给大家的也不算太复杂。
if __name__ == '__main__':
os.setsid()
但是我遇到了一个很麻烦的错误,提示“操作不允许”。
我正在使用最新稳定版的Django、Debian、Celery和Python。
1 个回答
3
Python中的 os.setsid()
可能会调用底层的库函数 setsid(3)
。
在 man 3 setsid
中,完整的错误信息部分是:
ERRORS
EPERM The process group ID of any process equals the PID of the call-
ing process. Thus, in particular, setsid() fails if the calling
process is already a process group leader.
换句话说,setsid()
失败的唯一原因是调用这个函数的进程已经是一个进程组的领导者。所以:你可以忽略这个失败。要确认这一点,可以比较在 os.setsid()
失败时从 getpid()
和 getpgid()
得到的结果:
#!/usr/bin/env python
import os
import errno
if __name__ == '__main__':
try:
os.setsid()
except OSError, (err_no, err_message):
print "os.setsid failed: errno=%d: %s" % (err_no, err_message)
print "pid=%d pgid=%d" % (os.getpid(), os.getpgid(0))
当我运行上面的代码时,我得到:
os.setsid failed: errno=1: Operation not permitted
pid=17025 pgid=17025
注意,进程ID(pid)等于进程组ID(pgid),这意味着这个进程确实已经是一个进程组的领导者。
附注:是的,Python在遇到错误时抛出异常,这确实让人困惑,因为有时候只需要一个简单的错误返回码就能区分成功和失败(就像我们熟悉的Unix libc
API那样)。不幸的是,这就是Python系统调用接口的实现方式,所以你需要用 try: except ...:
的结构来包裹许多系统调用,以防止Python中断你的代码。