os模塊中的fork方法可以創(chuàng)建一個(gè)子進(jìn)程。相當(dāng)于克隆了父進(jìn)程
os.fork()
子進(jìn)程運(yùn)行時(shí),os.fork方法會(huì)返回0;
而父進(jìn)程運(yùn)行時(shí),os.fork方法會(huì)返回子進(jìn)程的PID號。
所以可以使用PID來區(qū)分兩個(gè)進(jìn)程:
#!/usr/bin/env python #coding=utf8 from time import sleep import os try: pid = os.fork() except OSError, e: pass sleep(30)
運(yùn)行代碼,查看進(jìn)程:
[root@localhost ~]# python test2.py &[1] 2464[root@localhost ~]# ps -lF S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD4 S 0 2379 2377 0 80 0 - 28879 wait pts/1 00:00:00 bash0 S 0 2464 2379 0 80 0 - 31318 poll_s pts/1 00:00:00 python1 S 0 2465 2464 0 80 0 - 31318 poll_s pts/1 00:00:00 python0 R 0 2466 2379 0 80 0 - 37227 - pts/1 00:00:00 ps
可以看出第二條python進(jìn)程就是第一條的子進(jìn)程。
如剛剛所說os.fork()方法區(qū)分子進(jìn)程和父進(jìn)程
#-*- coding:utf-8 -*- from time import sleepimport os print('start+++++++++++++')#創(chuàng)建子進(jìn)程之前聲明的變量source = 10try: pid = os.fork() print('pid=',pid) if pid == 0: #子進(jìn)程 print("this is child process.") source = source - 1 #在子進(jìn)程中source減1 else: #父進(jìn)程 print("this is parent process." ) print(source)except (OSError,e): passprint('END---------------') 面代碼中,在子進(jìn)程創(chuàng)建前,聲明了一個(gè)變量source,然后在子進(jìn)程中減1,最后打印出source的值,顯然父進(jìn)程打印出來的值應(yīng)該為10,子進(jìn)程打印出來的值應(yīng)該為9。
[root@localhost ~]# python test3.pystart+++++++++++++pid= 2550this is parent process.10END---------------pid= 0this is child process.9END---------------
簡單守護(hù)進(jìn)程例子:
def main(): ''' 程序要執(zhí)行的邏輯代碼 ''' pass # 創(chuàng)建守護(hù)進(jìn)程函數(shù)def createDaemon(): ''' 第一塊(創(chuàng)建第一個(gè)子進(jìn)程) ''' # fork 第一個(gè)子進(jìn)程(如果fork成功,父進(jìn)程自殺,只留下第一個(gè)子進(jìn)程繼續(xù)向下運(yùn)行) try: if os.fork() > 0: sys.exit(0) except OSError, error: print '(fork第一個(gè)子進(jìn)程失敗)fork #1 failed: %d (%s)' % (error.errno, error.strerror) sys.exit(1) ''' 第一塊結(jié)束 ''' ###### 第一個(gè)進(jìn)程創(chuàng)建成功后,它的ppid = 1,已是一個(gè)守護(hù)里程了,但有些功能上還是有被限制。 ###### 所以下面再來創(chuàng)建一個(gè)子進(jìn)程。第二次創(chuàng)建的子進(jìn)程限制就沒那多了,有可能沒有,所以最安全。 ###### 下面來創(chuàng)建第二個(gè)子進(jìn)程。 os.chdir('/') # 把第一個(gè)子進(jìn)程的工作目錄切換到 / (根目錄) os.setsid() # 第一個(gè)子進(jìn)程取得程序的權(quán)限 os.umask(0) # 第一個(gè)子進(jìn)程取得工作目錄的所有操作(目錄的rwx) ''' 第二塊(創(chuàng)建第二個(gè)子進(jìn)程) ''' # fork 第二個(gè)子進(jìn)程(如果fork成功,第一個(gè)子進(jìn)程自殺,只留下新創(chuàng)建的第二個(gè)子進(jìn)程) try: pid = os.fork() if pid > 0: print 'Daemon PID %d' % pid sys.exit(0) except OSError, error: print '(fork第二個(gè)子進(jìn)程失敗)fork #2 failed: %d (%s)' % (error.errno, error.strerror) sys.exit(1) ''' 第二塊結(jié)束 ''' ####### 通過上面兩個(gè) try 語句塊,只留下了第二個(gè)子進(jìn)程在運(yùn)行了。這時(shí)第二個(gè)子進(jìn)程的ppid=1。 ####### 創(chuàng)建的第二個(gè)子進(jìn)程,可以說是一個(gè)不受限的守護(hù)進(jìn)程了。 # 重定向標(biāo)準(zhǔn)IO(因?yàn)橹挥械诙€(gè)子進(jìn)程在運(yùn)行了,所以也就是指定整個(gè)程序的輸入、輸出、錯(cuò)誤流) # sys.stdout.flush() # 清除程序運(yùn)行空間的輸出流 # sys.stderr.flush() # 清除程序運(yùn)行空間的錯(cuò)誤流 # inputS = file("/dev/null", 'r') # 定義一個(gè) inputS 文件對象 # outputS = file("/dev/null", 'a+') # 定義一個(gè) outputS 文件對象 # errorS = file("/dev/null", 'a+', 0) # 定義一個(gè) errorS 文件對象 # os.dup2(inputS.fileno(), sys.stdin.fileno()) # 把程序的輸入流重定向到上面定義的 inputS 文件對象上。 # os.dup2(so.fileno(), sys.stdout.fileno()) # 把程序的 輸出流 重定向到上面定義的 outputS 文件對象上。 # os.dup2(se.fileno(), sys.stderr.fileno()) # 把程序的 錯(cuò)誤流 重定向到上面定義的 errorS 文件對象上。 main() # main函數(shù)為真正程序邏輯代碼 if __name__ == "__main__": if platform.system() == "Linux": createDaemon() else: sys.exit()
新聞熱點(diǎn)
疑難解答
圖片精選