python - python 多进程发生了一些奇怪的事情

标签 python

我刚刚测试了 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/

相关文章:

python - 绘制和更新车速表指针

python - 使用另一列中的值对 str.starts_with() 进行极坐标分析

python - QtreeWidget样式表: change selected item style

python - Tensorflow:DropoutWrapper 导致不同的输出?

python - 为什么我的对象没有转换为字符串?

python - 使用python将一列转换为多行

python - 与 .join() pyspark 相反

python - 从 python 运行 bash 命令并捕获文件对象

python - 在 Ruby 中,为什么 `Array.length` 会给出 NoMethodError?

python - 如何使用正则表达式删除所有不在括号内的字符