繁体   English   中英

Python 多处理在进程之间共享变量

[英]Python Multiprocessing Sharing Variables Between Processes

我正在尝试编写一个多处理程序,它在子进程之间共享一个或多个变量(值或矩阵)。 在我当前的测试程序中,我试图生成两个进程,每个进程共享 num 变量。 每个将变量加 1,然后打印。 但是,每当我尝试运行该程序时,它都会告诉我发生了类型错误,并说“同步”object 不可迭代。 我怎样才能让它工作?

代码如下所示:

import multiprocessing
import os
import time

def info(title):
    print(title)
    print('module name:', __name__)
    print('parent process:', os.getppid())
    print('process id:', os.getpid())

def f(num):
    while True:
        time.sleep(1.5)
        num = num + 1
        print("process 1: %i \n" % num)
        if num > 50:
            break

def f2(num):
    while True:
        num= num + 1
        print("process 2: %i \n" % num)
        time.sleep(1.9)
        if num > 50:
            break

if __name__ == '__main__':
    data = multiprocessing.Value('i',0)
    p = multiprocessing.Process(target=f, args=(data))
    j = multiprocessing.Process(target=f2, args=(data))
    p.start()
    j.start()

“同步”object 不是在尝试创建第一个进程时运行程序的可迭代结果:p = multiprocessing.Process(target=f, args=(data))

我不确定使用队列是否可行,因为我最终希望有一个程序有一个循环过程,另一个程序偶尔会获取从循环过程返回的最新结果。

这将清除代码中的错误。 你需要守护进程,更重要的是你需要让 args 输入一个元组

    data = multiprocessing.Value('i',0)
    p = multiprocessing.Process(target=f, args=(data,))
    p.daemon = True
    p.start()
    j = multiprocessing.Process(target=f2, args=(data,))
    j.daemon=True
    j.start()

您的代码有几个问题:

  1. 当您创建一个multiprocessing.Value实例(在您的情况下为num )时,您必须使用该实例的value属性来读取或写入该共享变量的实际值。
  2. 增加这样一个实例,即使你像我所做的那样用num.value += 1替换num.value = num.value + 1 ,也不是原子操作。 相当于temp = num.value; temp += 1; num.value = temp temp = num.value; temp += 1; num.value = temp temp = num.value; temp += 1; num.value = temp ,这意味着这种递增必须在为此类同步实例提供的锁的控制下进行,以确保该值真正 increm.neted。 否则,两个进程可能会读取相同的值并将其递增到相同的最终值,而您只会递增该值一次而不是两次。
  3. multiprocessing.Process初始值设定项的args参数应该是可迭代的,其中可迭代的每个元素都成为辅助函数ff2的参数。 当您指定args=(data)时,括号没有任何作用,相当于简单地指定args=data并且data不是可迭代的。 你需要有args=(data,) 请注意逗号 (',') 这样(data,)现在是包含单个元素datatuple (即可迭代对象),而不是带括号的表达式
import multiprocessing
import os
import time

def info(title):
    print(title)
    print('module name:', __name__)
    print('parent process:', os.getppid())
    print('process id:', os.getpid())

def f(num):
    while True:
        time.sleep(1.5)
        with num.get_lock():
            num.value += 1
            print("process 1: %i \n" % num.value)
            if num.value > 50:
                break

def f2(num):
    while True:
        with num.get_lock():
            num.value += 1
            print("process 2: %i \n" % num.value)
            time.sleep(1.9)
            if num.value > 50:
                break

if __name__ == '__main__':
    data = multiprocessing.Value('i',0)
    p = multiprocessing.Process(target=f, args=(data,))
    j = multiprocessing.Process(target=f2, args=(data,))
    p.start()
    j.start()
    p.join()
    j.join()
    print(data.value)

印刷:

...
process 2: 47

process 1: 48

process 2: 49

process 1: 50

process 2: 51

process 1: 52

52

但请注意,在上面的代码中,每个进程都获取并持有锁很长时间,以阻止任何其他进程获取锁。 我们可以通过以下方式最小化持有锁的时间(这样程序将更快完成):

import multiprocessing
import os
import time

def info(title):
    print(title)
    print('module name:', __name__)
    print('parent process:', os.getppid())
    print('process id:', os.getpid())

def f(num):
    while True:
        time.sleep(1.5)
        with num.get_lock():
            num.value += 1
            saved_value = num.value
        print("process 1: %i \n" % saved_value)
        if saved_value > 50:
            break

def f2(num):
    while True:
        with num.get_lock():
            num.value += 1
            saved_value = num.value
        print("process 2: %i \n" % saved_value)
        time.sleep(1.9)
        if saved_value > 50:
            break

if __name__ == '__main__':
    data = multiprocessing.Value('i',0)
    p = multiprocessing.Process(target=f, args=(data,))
    j = multiprocessing.Process(target=f2, args=(data,))
    p.start()
    j.start()
    p.join()
    j.join()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM