1. 程式人生 > >python中多程序的相關技術

python中多程序的相關技術



--如何建立的子執行緒。
self.pid = os.fork()
if self.pid == 0:
code = process_obj._bootstrap()
sys.stdout.flush()
sys.stderr.flush()
os._exit(code)
os fork 建立了一個新的程序,該子程序和父程序唯一不同的就是Pid,父id的pid不為空,所以從這個判斷條件開始兩個程序已經開始
執行不同的程式碼。
其中_bootstrap函式,做了幾件事情,初始化子程序的上下文環境,以及執行相應的函式,這段程式碼在process。run()函式中,和C的非常相似。
由於子程序是父程序的複製,所以按道理說,在執行完上述的程式碼後,應該會返回到主函式,因為父程序是這麼幹的。
但是由於在分支的程式碼塊中,有一個exit的函式,所以就退出了,不會再返回主程序去跑父程序的程式碼塊
--父執行緒如何監控子程序的狀態
在主程序中,在建立了子程序之後,
有段程式碼如下:_current_process._children.add(self),會將剛建立的子程序新增到_children的列表裡面,這樣的話,父程序就維繫了和子程序的關係。
並且將子程序的所有資訊都放置在_children裡面。
python的process的join是父程序在等待子程序結束的資訊。如果子程序結束的話,
Process.join() 呼叫 Popen.wait(),而 wait() 內部則通過 poll() 呼叫 os.waitpid() 等待子程序終止。
每個子程序在執行完成後,都會有:util._exit_function(),先將子程序的子程序給清理乾淨。最後返回return exitcode
--子程序異常結束,父程序如何處理。
如果子程序執行異常,丟擲了個異常,或者在程序的具體程式碼模組的執行中遇到了exit(0)的,父程序會捕獲這些異常,並且正確返回。
子程序程式碼中如果return 或者沒有返回,都是ok的。
子程序程式碼中如果有exit(-1),也是可以正常退出的。也是可以正常的把錯誤的輸出和,正常的輸出轉向到控制檯。
子程序程式碼中如果有跑出異常,那麼也是可以將所有的資訊輸出。
子程序如果被異常終止了,那麼該程序會屬於正常終止,所有沒有儲存到磁碟的資訊都會被丟失,父程序能夠收到該子程序正常結束的訊息,能夠正常終止。
所以子程序中無論發生了什麼,都會正常的返回,除非其中某個語句卡住了。
--如果子程序卡住了,那麼父程序能做什麼
正常情況下,子程序應該不會卡住的,但是比如讀hdfs的檔案,或者呼叫對方的http請求,都會出現卡住的情況。
那麼我們儘量被保證不會這樣的情況,都會設定timeout的時間。
一旦卡住,那麼直接呼叫terminate ,那麼就會出現殭屍程序。
dwdev    28346 28345  0 21:56 pts/0    00:00:00 [python] <defunct>
dwdev    28347 28345  0 21:56 pts/0    00:00:00 [python] <defunct>
這種情況一般是由於子程序的退出的時候,程序內部有些資訊沒有被處理完。
a=Queue()
    b=Array('i',range(10))
    for i in threadLen:
        t=Process(target=worker,args=(a,b))
        threads.append(t)
    for i in threadLen:
        threads[i].start()
    for i in threadLen:
        threads[i].terminate()
        print "i is:"+str(i)
    #    threads[i].join() 
    print a.get()#在這裡的時候卡住了。。
    print b[0]
    print b[1]
如果改成下面的形式,那麼就可以自然退出。
       t=Process(target=worker,args=(str(i)))
        threads.append(t)
    for i in threadLen:
        threads[i].start()
    for i in threadLen:
        threads[i].terminate()
        print "i is:"+str(i)
    #    threads[i].join() 
    print "finished"
    這樣就可以自然退出,
    前面這個例子和後面這個例子,經過多次的測試,發現問題是由於queue這個物件造成的,
    queue的物件中的get方法,當queue中沒有物件的時候,那麼就會卡住主程序,而此時子程序已經結束了,沒有join的函式處理程序終止的資訊。
    導致子程序都變成殭屍程序。
    如果在terminate之後,加了join的函式,那麼就沒有defunct的存在了。這個defunt就是子程序的訊號沒有被及時處理,導致子程序無法正常退出。
    
http://www.erlangsir.com/2011/04/22/python-library-multiprocessing/