我想迭代一个带有2个函数的列表,使用多处理,一个函数遍历main_list,从前导和其他尾随,我希望这个函数每次遍历样本列表(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
请注意,我不知道在其中一个进程找到重复元素后如何终止这两个进程!!
答案 0 :(得分:1)
您的代码中存在各种其他问题,但由于我已经在其他问题上解释了这些问题,因此我不会在此处进入。
新问题是您没有join
您的子流程。在您的线程版本中,这不是一个问题,因为您的主线程意外地有一个&#34;永久阻止&#34;在结束之前。但是在这里,你还没有,所以当后台进程仍在运行时,主进程到达脚本的末尾。
当发生这种情况时,它并没有完全定义你的代码会做什么。 * 但基本上,你正在销毁管理器对象,这会关闭管理器服务器。后台进程仍在使用它,因此他们在下次尝试访问托管对象时会引发异常。
解决方案是将p1.join()
和p2.join()
添加到脚本的末尾。
但这真的只会让你回到与线程代码相同的情况(除了最后不会永远阻塞)。您仍然拥有完全序列化的代码,并且竞争条件很严重,等等。
如果你很好奇为什么会这样:
在脚本结束时,所有模块的全局变量都超出范围。 ** 由于这些变量是管理器和过程对象的唯一引用,对象被垃圾收集,并且它们的析构函数被调用。
对于管理器对象,析构函数会关闭服务器。
对于进程对象,我并不完全确定,但我认为析构函数 nothing (而不是加入它和/或中断它)。相反,它有一个atexit函数,它在所有析构函数之后运行,它们连接任何仍在运行的进程。 ***
所以,首先经理离开,然后主要过程开始等待孩子们完成;下次每次尝试访问托管对象时,它都会失败并退出。一旦所有人都这样做,主要过程就会等待并退出。
* 3.2中的multiprocessing
更改和3.4中的关闭更改使事情变得更加清晰,所以如果我们不讨论2.7,那么#34;这里&# 39;经常发生的事情,但并非总是如此。和&#34;这是在一个特定平台上的一个特定实现中发生的事情&#34;。
**这实际上并不是由2.7保证,并且垃圾收集所有模块&#39;全局变量并不总是发生。但是在这个特别简单的情况下,我非常确定它将始终以这种方式工作,至少在CPython中,尽管我不想尝试解释原因。
***这肯定是它如何与线程一起工作,至少在Unix上的CPython 2.7上......再次,这根本没有记录在2.x中,所以你只能告诉它通过阅读源代码或试验对您来说重要的平台/实现/版本......我不想通过源跟踪这个问题,除非有可能找到令人费解或有趣的东西。子>