import os import sys from time import sleep try: pid = os.fork() if pid > 0: sys.exit(0) # Exit parent. pid = os.fork()
os.setsid()
os.chdir(self.curdir)
os.umask(022)
if pid > 0: sys.exit(0) # Exit parent. except OSError, e: sys.stderr.write("fork failed: (%d) %s\n" % (e.errno, e.strerror)) sys.exit(1) while 1: sleep(1)
fork用戶將當前進程分叉,即新建一個子進程,這樣,運行完pid=os.fork()這條語句后,就有兩個進程,這兩個進程都會獨自運行下面的代碼,同時每個進程都有一個pid,子線程的pid為0
派生一個守護進程后,通過while來實現該進程一直在后台運行
.ps -ajx 參數說明:ppid 父進程id,pid 進程id,pgid 進程組id,sid 會話期id
一個進程組包含多個進程,一個會話期包含多個進程組,一個會話期擁有一個終端,
如果在該終端輸入退出(ctrl+c)命令,將關閉改會話期包含的所以進程
創建守護進程步驟
目的:使子進程不會擁有控制終端,即不要繼承父進程的進程組id和會話組id,也就是使子進程成為進程組組長和會話組組長
1.創建子進程。fork產生子進程,由於有父進程,所以該子進程不會是進程組組長和會話期組長
2.脫離控制終端。通過setid方法,使子進程成為 新的會話期 組長,由於該會話期只有一個進程,所以該子進程也是進程組組長。這是改會話期組長是沒有可控制終端的
3.禁止進程重新打開控制終端 。現在,進程已經成為無終端的會話組長,但它可以重新申請打開一個控制終端。可以通過使進程不再成為會話組長來禁止進程重新打開控制終端:
4.關閉打開的文件描述符
5.改變當前工作目錄
6.重設文件創建掩碼
7.從子進程中fork另一個子進程,該子進程不是進程組組長,也不是會話期組長,是真正的守護進程
為了更好地觀察創建守護進程中,各種身份的變化,在這里做一個測試
測試代碼:
#encoding=utf-8 __author__ = 'kevinlu1010@qq.com' import os import sys from time import sleep try: pid = os.fork() print '完成第一次fork' sleep(10) #sleep1 if pid > 0: sys.exit(0) # Exit first parent. os.setsid() print '執行setsid,使子進程成為會話期組長' sleep(10) #sleep2 os.chdir('/') os.umask(022) #設置當前權限掩碼,同時返回先前的權限掩碼。 print '完成修改工作目錄和權限掩碼' sleep(10) #sleep3 pid = os.fork() print '完成第二次fork' sleep(10) #sleep4 if pid > 0: sys.exit(0) # Exit first parent. print '守護進程啟動完成' sleep(10) #sleep5 except OSError, e: sys.stderr.write("fork failed: (%d) %s\n" % (e.errno, e.strerror)) sys.exit(1) while 1: sleep(1)
這里一共有5個sleep,我在每個sleep都用ps -axj|grep python命令查看進程的id變化,分別為:
標題頭:
父進程id 進程id 進程組id 會話期id
進程組或會話期的id與該進程組或會話期的組長的進程id相同
例如進程id是7000的進程,它的進程組id是6000,即7000所屬的進程組的id是6000,該進程組的組長是進程id為6000的進程,會話期同理
sleep1:
第一個進程為父進程,第二個為子進程,他們有共同的進程組id和會話期id
sleep2:

父進程退出,剩下子進程,通過setsid命令,使子進程成為進程組組長和會話期組長
sleep3:

這個步驟id不會變化
sleep4:

子進程再fork一個子進程,之前的子進程變成父進程,父進程與子進程擁有共同的進程組id和會話期id,
sleep5:

父進程退出,子進程既不是進程組組長也不是會話期組長,子進程與第一個父進程完全脫離關系,子進程沒有控制終端,達到守護進程需要的條件
參考資料:http://www.01happy.com/python-fork-create-process/
http://blog.csdn.net/mr_jj_lian/article/details/7252222