2016-07-18 6 views
0

Можно ли инициализировать состояние подкласса multiprocessing.Process в методе __init__()? Или это приведет к дублированию использования ресурсов при вилке процесса? Возьмем такой пример:Инициализация подкласса многопроцессорности 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 - плохая идея?

Обратите внимание, что мои процессы длинные и предназначены для блокировки ввода-вывода.

ответ

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 forked processes] (http://stackoverflow.com/a/6314744/344286). –

+0

Добавление 'os.getpid()' к имени файла подтверждает, что файл открывается только один раз. Это имеет смысл, так как дескриптор файла может быть передан новому процессу без проблем. Я не верю, что процессы имеют хоть какую-то память, так что любая память, которую я выделяю в конструкторе, дублируется? – Mike

Смежные вопросы