我刚刚测试了 python 多重处理来读取文件或全局变量,但是发生了一些奇怪的事情。
例如:
import multiprocessing
a = 0
def test(lock, name):
global a
with lock:
for i in range(10):
a = a + 1
print "in process %d : %d" % (name, a)
def main():
lock = multiprocessing.Lock()
p1 = multiprocessing.Process(target=test, args=(lock, 1))
p2 = multiprocessing.Process(target=test, args=(lock, 2))
p1.start()
p2.start()
p1.join()
p2.join()
print "in main process : %d" % a
if __name__=='__main__':
main()
程序读取了一个全局变量,但输出是:
in process 1 : 10
in process 2 : 10
in main process : 0
子进程似乎无法正确获取和编辑全局变量。另外,如果我改变程序来读取文件,每个子进程都会完整地读取文件,忽略锁。
那么这些是如何发生的呢?那么如何解决这个问题呢?
最佳答案
全局变量不在进程之间共享。当您创建并启动一个新的 Process() 时,该进程会在当前 Python 解释器的单独“克隆”副本中运行。从 Process()
内更新变量只会将变量本地更新到其更新所在的特定进程。
要在 Python 进程之间共享数据,我们需要 multiprocessing.Pipe()
,一个multiprocessing.Queue()
,一个multiprocessing.Value()
,一个multiprocessing.Array()
或其他多处理安全容器之一。
这是一个基于您的代码的示例:
import multiprocessing
def worker(lock, counter, name):
with lock:
for i in range(10):
counter.value += 1
print "In process {}: {}".format(name, counter.value)
def main():
lock = multiprocessing.Lock()
counter = multiprocessing.Value('i', 0)
p1 = multiprocessing.Process(target=worker, args=(lock, counter, 1))
p2 = multiprocessing.Process(target=worker, args=(lock, counter, 2))
p1.start()
p2.start()
p1.join()
p2.join()
print "In main process: {}".format(counter.value)
if __name__=='__main__':
main()
这给了我:
In process 1: 10
In process 2: 20
In main process: 20
现在,如果您确实想使用全局变量,可以使用 multiprocessing.Manager()
,但我认为第一种方法更可取,这是一个“较重”的解决方案。这是一个例子:
import multiprocessing
manager = multiprocessing.Manager()
counter = manager.Value('i', 0);
def worker(lock, name):
global counter
with lock:
for i in range(10):
counter.value += 1
print "In process {}: {}".format(name, counter.value)
def main():
global counter
lock = multiprocessing.Lock()
p1 = multiprocessing.Process(target=worker, args=(lock, 1))
p2 = multiprocessing.Process(target=worker, args=(lock, 2))
p1.start()
p2.start()
p1.join()
p2.join()
print "In main process: {}".format(counter.value)
if __name__=='__main__':
main()
关于python - python 多进程发生了一些奇怪的事情,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38343090/