2014-09-06 184 views
3

好吧熊與我似乎有一些關於谷歌的答案,但我根本無法得到它。os.setsid操作不允許

我在Django Celery環境中使用兩條叉子後運行它。我不知道這些是否會改變某些事情,但我認爲他們沒有改變。

沒有多少碼留下作爲一個強大的

if __name__ == '__main__': 
    os.setsid() 

賦予我美麗操作不允許

我運行最新的穩定的Django,Debian的,芹菜和Python版本。

+0

您的示例不起作用,因爲如果調用進程已經是進程組領導,則setsid()失敗(來自手冊頁setsid(2)中的「Operation not permitted」操作的描述)。這並不能回答你的問題,因爲在fork(2)之後,你不再是一個過程組的領導者。 – Phillip 2014-12-11 08:25:18

回答

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()失敗的唯一原因,是當調用進程已經是一個進程組長。埃爾戈:你可以忽略失敗。爲了驗證這種情況下,比較你getpid()getpgid()得到什麼時os.setsid()失敗:

#!/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)等於process-group-id(pgid),這意味着這個過程確實已經是一個過程組領導。

P.S:是的,如果一個簡單的錯誤返回代碼足以區分成功與失敗(就像熟悉的Un * x libc API的行爲),那麼引發異常是python的一個莫名其妙的功能。不幸的是,python系統調用接口是如何實現的,所以你需要用try: except ...:結構包裝很多系統調用,以防止python中止你的代碼。