Iterar sobre la lista de liderar y arrastrar con multiproceso

Quiero iterar sobre una lista con 2 funciones usando multiprocesamiento, una función iterar sobre main_list desde el principio y otra desde el final, quiero esta función cada vez que iterate sobre la lista de muestra ( g ) ponga el elemento en la lista principal hasta que uno de ellos encontrar un duplicado en la lista, entonces quiero terminar ambos procesos y devolver los elementos vistos.

Espero que el primer proceso vuelva:

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

Y la segunda vuelta:

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

este es mi código que devuelve un error:

 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() 

Y este es el 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 "", 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 "", 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 

Tenga en cuenta que no tengo idea de cómo terminar ambos procesos después de que uno de ellos encuentre un elemento duplicado.

Hay muchos otros problemas en su código, pero como ya los expliqué en su otra pregunta, no los abordaré aquí.

El nuevo problema es que no estás join tus procesos secundarios. En su versión con hilos, esto no fue un problema solo porque su hilo principal tuvo un “bloque para siempre” accidentalmente antes del final. Pero aquí, no tienes eso, por lo que el proceso principal llega al final de la secuencia de comandos mientras los procesos en segundo plano aún se están ejecutando.

Cuando esto sucede, no se define por completo lo que hará su código. * Pero básicamente, está destruyendo el objeto del administrador, que apaga el servidor del administrador mientras los procesos en segundo plano todavía lo están utilizando, por lo que generarán excepciones la próxima vez que intenten acceder a un objeto administrado.

La solución es agregar p1.join() y p2.join() al final de su script.

Pero eso realmente solo hace que regreses a la misma situación que tu código de subprocesos (excepto que no se bloquea para siempre al final). Todavía tienes un código que está completamente serializado, y una condición de gran carrera, y así sucesivamente.


Si tienes curiosidad por qué sucede esto:

Al final de la secuencia de comandos, todas las variables globales de su módulo quedan fuera de scope. ** Dado que esas variables son la única referencia que tiene para el administrador y los objetos de proceso, esos objetos se recolectan en la basura y se llama a sus destructores.

Para un objeto administrador, el destructor apaga el servidor.

Para un objeto de proceso, no estoy completamente seguro, pero creo que el destructor no hace nada (en lugar de unirlo y / o interrumpirlo). En su lugar, hay una función atexit, que se ejecuta después de todos los destructores, que se une a cualquier proceso en ejecución. ***

Entonces, primero el administrador se va, luego el proceso principal comienza a esperar a que los niños terminen; la próxima vez que cada uno intente acceder a un objeto administrado, fallará y se cerrará. Una vez que todos ellos hacen eso, el proceso principal termina de esperar y sale.


* Los cambios de multiprocessing en 3.2 y los cambios de apagado en 3.4 hacen las cosas mucho más limpias, por lo que si no estuviéramos hablando de 2.7, habría menos “esto es lo que suele ocurrir pero no siempre” y “esto es lo que sucede en una implementación particular en una plataforma particular “.

** Esto no está realmente garantizado por 2.7, y la recolección de basura en todos los módulos de los módulos no siempre sucede. Pero en este caso simple en particular, estoy bastante seguro de que siempre funcionará de esta manera, al menos en CPython, aunque no quiero tratar de explicar por qué.

*** Definitivamente, así es como funciona con los subprocesos, al menos en CPython 2.7 en Unix … una vez más, esto no está documentado en 2.x, por lo que solo puede saberlo leyendo la fuente o experimentando en las plataformas / implementaciones / versiones que son importantes para usted … Y no quiero rastrear esto a través de la fuente a menos que sea probable que haya algo sorprendente o interesante de encontrar.