2016-07-18 106 views
0

可以在__init__()方法中初始化multiprocessing.Process子類的狀態嗎?或者當進程分叉時會導致資源利用率重複?就拿這個例子:Python多處理子類的初始化

from multiprocessing import Process, Pipe 
import time 

class MyProcess(Process): 
    def __init__(self, conn, bar): 
     super().__init__() 
     self.conn = conn 
     self.bar = bar 
     self.databuffer = [] 

    def foo(self, baz): 
     return self.bar * baz 

    def run(self): 
     '''Process mainloop''' 
     running = True 
     i = 0 
     while running: 
      self.databuffer.append(self.foo(i)) 
      if self.conn.poll(): 
       m = self.conn.recv() 
       if m=='get': 
        self.conn.send((i, self.databuffer)) 
       elif m=='stop': 
        running = False 
      i += 1 
      time.sleep(0.1) 


if __name__=='__main__': 
    conn, child_conn = Pipe() 
    p = MyProcess(child_conn, 5) 
    p.start()  
    time.sleep(2) 

    # Touching the instance does not affect the process which has forked. 
    p.bar=1 
    print(p.databuffer) 

    time.sleep(2) 
    conn.send('get') 
    i,data = conn.recv() 
    print(i,data) 
    conn.send('stop') 
    p.join() 

正如我在代碼注意,你不能與處理,通過實例p只能通過Pipe,如果我做了一堆在__init__方法設置的溝通,比如創建文件句柄,這個過程分叉時如何複製?

這是否意味着子類multiprocessing.Process以同樣的方式,你會threading.Thread一個壞主意?

請注意,我的進程長時間運行並意味着處理阻塞IO。

回答

1

這很容易測試。在__init__,添加以下內容:

self.file = open('does_it_open.txt'.format(self.count), 'w') 

然後運行:

$ strace -f python youprogram.py 2> test.log 
$ grep does_it_open test.log 
open("does_it_open.txt", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 6 

這意味着,至少在我的系統,複製你的代碼,並補充說,呼叫,文件被打開一次,並且只有一次。

欲瞭解更多關於strace的魔法,請查看this fantastic blog post

+0

我認爲'strace'只是看着主流程。當我將'open()'調用移動到'run()'方法時,它不會出現在'strace'中。 – Mike

+0

好的。將'-f'標誌添加到[include分叉進程](http://stackoverflow.com/a/6314744/344286)。 –

+0

將'os.getpid()'追加到文件名確認該文件只打開一次。這很有意義,因爲文件句柄可以毫無困難地傳遞給新進程。我不相信這些進程共享任何內存,但是我在構造函數中分配的任何內存都是重複的? – Mike