我刚刚测试了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
似乎子流程无法正确获取和编辑全局变量。此外,如果我更改程序以读取文件,则每个子进程将完全读取文件,忽略锁定。
那么这些怎么发生?以及如何解决这个问题?
答案 0 :(得分:1)
全局变量不在进程之间共享。当您创建并启动一个新的Process()
时,该进程将在一个单独的"克隆"内部运行。当前Python解释器的副本。从Process()
内更新变量只会将变量本地更新为更新的特定进程。
要在Python流程之间共享数据,我们需要multiprocessing.Pipe()
,multiprocessing.Queue()
,multiprocessing.Value()
,multiprocessing.Array()
或其他多处理安全容器。< / p>
以下是基于您的代码的示例:
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()
,但我认为第一种方法更可取,这是一个更重的&#34;解。这是一个例子:
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()