Итерация по списку из ведущего и конечного с многопроцессорной обработкой

Я хочу перебирать список с помощью 2-х функций, используя многопроцессорную обработку одной функции по основному списку из ведущего и другого из трейлинга, я хочу эту функцию каждый раз, когда итерации над списком образцов ( g ) помещают элемент в основной список, пока один из них найти дубликат в списке, тогда я хочу, чтобы завершить оба процесса и вернуть видимые элементы.

Я ожидаю, что первый процесс вернется:

 ['a', 'b', 'c', 'd', 'e', 'f'] 

И второе возвращение:

 ['l', 'k', 'j', 'i', 'h', 'g'] 

это мой код, который возвращает ошибку:

 from multiprocessing import Process, Manager manager = Manager() d = manager.list() # Fn definitions and such def a(main_path,g,l=[]): for i in g: l.append(i) print 'a' if i in main_path: return l main_path.append(i) def b(main_path,g,l=[]): for i in g: l.append(i) print 'b' if i in main_path: return l main_path.append(i) g=['a','b','c','d','e','f','g','h','i','j','k','l'] g2=g[::-1] p1 = Process(target=a, args=(d,g)) p2 = Process(target=b, args=(d,g2)) p1.start() p2.start() 

И это Traceback :

 a Process Process-2: Traceback (most recent call last): File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap self.run() File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run self._target(*self._args, **self._kwargs) File "/home/bluebird/Desktop/persiantext.py", line 17, in a if i in main_path: File "<string>", line 2, in __contains__ File "/usr/lib/python2.7/multiprocessing/managers.py", line 755, in _callmethod self._connect() File "/usr/lib/python2.7/multiprocessing/managers.py", line 742, in _connect conn = self._Client(self._token.address, authkey=self._authkey) File "/usr/lib/python2.7/multiprocessing/connection.py", line 169, in Client b c = SocketClient(address) File "/usr/lib/python2.7/multiprocessing/connection.py", line 304, in SocketClient s.connect(address) File "/usr/lib/python2.7/socket.py", line 224, in meth return getattr(self._sock,name)(*args) error: [Errno 2] No such file or directory Process Process-3: Traceback (most recent call last): File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap self.run() File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run self._target(*self._args, **self._kwargs) File "/home/bluebird/Desktop/persiantext.py", line 27, in b if i in main_path: File "<string>", line 2, in __contains__ File "/usr/lib/python2.7/multiprocessing/managers.py", line 755, in _callmethod self._connect() File "/usr/lib/python2.7/multiprocessing/managers.py", line 742, in _connect conn = self._Client(self._token.address, authkey=self._authkey) File "/usr/lib/python2.7/multiprocessing/connection.py", line 169, in Client c = SocketClient(address) File "/usr/lib/python2.7/multiprocessing/connection.py", line 304, in SocketClient s.connect(address) File "/usr/lib/python2.7/socket.py", line 224, in meth return getattr(self._sock,name)(*args) error: [Errno 2] No such file or directory 

Обратите внимание, что я не знаю, как прекратить оба процесса после того, как один из них найдет дублированный элемент!

One Solution collect form web for “Итерация по списку из ведущего и конечного с многопроцессорной обработкой”

В вашем коде есть все другие проблемы, но, поскольку я уже объяснил их по вашему другому вопросу, я не буду вдаваться в них здесь.

Новая проблема заключается в том, что вы не join к своим дочерним процессам. В вашей потоковой версии это не было проблемой только потому, что ваш основной поток случайно имел «блок навсегда» до конца. Но здесь у вас этого нет, поэтому основной процесс достигает конца скрипта, пока фоновые процессы все еще работают.

Когда это произойдет, он не полностью определит, что будет делать ваш код. * Но в основном вы уничтожаете объект-менеджер, который отключает сервер-менеджер, в то время как фоновые процессы все еще используют его, поэтому они собираются сделать исключения в следующий раз, когда они попытаются получить доступ к управляемому объекту.

Решение состоит в том, чтобы добавить p1.join() и p2.join() в конец вашего скрипта.

Но это действительно возвращает вас к той же ситуации, что и ваш код с резьбой (за исключением того, что он не блокируется навсегда в конце). У вас все еще есть код, который полностью сериализуется, и большое состояние гонки, и так далее.


Если вам интересно, почему это происходит:

В конце скрипта все глобальные параметры вашего модуля выходят за рамки. ** Поскольку эти переменные являются единственной ссылкой, которую вы имеете на менеджер и объекты процесса, эти объекты получают сбор мусора, и их деструкторы вызываются.

Для объекта-менеджера деструктор отключает сервер.

Для объекта процесса я не совсем уверен, но я думаю, что деструктор ничего не делает (вместо того, чтобы присоединяться к нему и / или прерывать его). Вместо этого есть функция atexit, которая запускается после всех деструкторов, которая объединяет любые все еще запущенные процессы. ***

Итак, сначала менеджер уходит, тогда главный процесс начинает ждать, пока дети закончат; в следующий раз, когда каждый пытается получить доступ к управляемому объекту, он выходит из строя и выходит. Как только все они это сделают, основной процесс заканчивается ожиданиями и выходами.


* multiprocessing изменения в 3.2 и изменения выключения в 3.4 делают вещи намного более чистыми, поэтому, если бы мы не говорили о 2.7, было бы меньше «вот что обычно происходит, но не всегда» и «вот что происходит в одной конкретной реализации на одной конкретной платформе ».

** На самом деле это не гарантируется 2,7, и сбор мусора всех глобальных модулей не всегда происходит. Но в этом конкретном простом случае я уверен, что он всегда будет работать таким образом, по крайней мере, в CPython, хотя я не хочу пытаться объяснить, почему.

*** Это определенно, как это работает с потоками, по крайней мере на CPython 2.7 в Unix … опять же, это совсем не документировано в 2.x, поэтому вы можете только сказать, читая источник или экспериментируя на платформах / реализациях / версии, которые важны для вас … И я не хочу отслеживать это через источник, если не может быть чего-то загадочного или интересного.

Python - лучший язык программирования в мире.