Fil*_*ter 5 python pool multiprocessing
我正在multiprocessing.Pool对象中使用该类并尝试执行以下操作:
from multiprocessing import Lock, Pool
class A:
def __init__(self):
self.lock = Lock()
self.file = open('test.txt')
def function(self, i):
self.lock.acquire()
line = self.file.readline()
self.lock.release()
return line
def anotherfunction(self):
pool = Pool()
results = pool.map(self.function, range(10000))
pool.close()
pool.join()
return results
Run Code Online (Sandbox Code Playgroud)
但是,我收到一个运行时错误,指出锁对象只能通过继承在进程之间共享。我对 Python 和多处理相当陌生。我怎样才能走上正确的轨道?
multiprocessing.Lock实例可以是multiprocessing.Process实例的属性。当主进程中创建一个带有锁属性的进程时,该锁存在于主进程\xe2\x80\x99s地址空间中。当调用 process\xe2\x80\x99sstart方法并运行调用 process\xe2\x80\x99srun方法的子进程时,必须将锁序列化/反序列化到子进程地址空间。这按预期工作:
from multiprocessing import Lock, Process\n\nclass P(Process):\n def __init__(self, *args, **kwargs):\n Process.__init__(self, *args, **kwargs)\n self.lock = Lock()\n def run(self):\n print(self.lock)\n\nif __name__ == \'__main__\':\n p = P()\n p.start()\n p.join()\nRun Code Online (Sandbox Code Playgroud)\n印刷:
\n<Lock(owner=None)>\nRun Code Online (Sandbox Code Playgroud)\n不幸的是,当您处理实例时,这不起作用multiprocessing.Pool。在您的示例中,self.lock是通过该方法在主进程中创建的__init__。但是,当Pool.map调用 invoke时self.function,锁无法序列化/反序列化到将运行此方法的已在运行的池进程。
解决方案是使用设置为该锁的全局变量来初始化每个池进程(现在将该锁作为该类的属性是没有意义的)。实现此目的的方法是使用pool 方法的初始化程序和initargs__init__参数。请参阅文档:
from multiprocessing import Lock, Pool\n\ndef init_pool_processes(the_lock):\n \'\'\'Initialize each process with a global variable lock.\n \'\'\'\n global lock\n lock = the_lock\n\nclass Test:\n def function(self, i):\n lock.acquire()\n with open(\'test.txt\', \'a\') as f:\n print(i, file=f)\n lock.release()\n def anotherfunction(self):\n lock = Lock()\n pool = Pool(initializer=init_pool_processes, initargs=(lock,))\n pool.map(self.function, range(10))\n pool.close()\n pool.join()\n\nif __name__ == \'__main__\':\n t = Test()\n t.anotherfunction()\nRun Code Online (Sandbox Code Playgroud)\n