【问题标题】:Multiprocessing synchronization between multiple processes (Python)多个进程之间的多进程同步(Python)
【发布时间】:2023-08-31 04:50:01
【问题描述】:

所以在大学实践课上有一个练习:

"创建将共享值定义为 0 的程序,然后创建和 启动 500 个进程,每个进程增加 共享值加 1,最后打印共享值。跑 这段代码几次,看看会发生什么,解释一下……”

最终版本如下:

from multiprocessing import Process, Value


n=Value('i', 0)

def fun():
        n.value+=1

for i in range(500):
        p=Process(target=fun).start()

print n.value

输出值在 420-480 范围内变化,我明白为什么。
问题是如果可能的话如何让它总是500? 我一直在阅读 Python 文档并找到了可能的解决方案 - Semaphore,但也许我不太了解它..
在信号量的情况下代码看起来:

from multiprocessing import Process, Value, Semaphore

n=Value('i', 0)
sem=Semaphore()

def fun():
        sem.acquire()
        n.value+=1
        sem.release()

for i in range(500):
    p=Process(target=fun).start()
print n.value

在这种情况下,最终输出在 492-495 范围内变化 - 更好。

附:不要建议我使用线程类中的线程 - 问题是关于多处理的。

【问题讨论】:

    标签: python synchronization multiprocessing semaphore


    【解决方案1】:

    您的进程未加入。因此,您的锁有效,但 n 的值在所有过程完成以增加它之前显示,因此 n

    from multiprocessing import Process, Value, Semaphore
    
    n=Value('i', 0)
    sem=Semaphore()
    
    def fun():
            sem.acquire()
            n.value+=1
            sem.release()
    
    pcs=[]
    for i in range(500):
        p=Process(target=fun)
        pcs.append(p)
        p.start()
    for i in pcs:
        i.join()
    print n.value
    

    【讨论】:

    • 你的代码像第一个版本一样工作,如果我在循环外定义 Lock,在定义函数之前,它就像信号量一样工作,因为信号量是修改后的锁
    • 嘿,我的错,问题似乎实际上是进程没有被加入,请检查编辑的代码,我运行它,它似乎工作正常。您设置的信号量运行良好。
    • 在您编辑的代码中对我来说毫无意义.. 我想要的是并行执行所有进程,如果我在启动后加入每个进程,它就像正常循环'for i in range( 500)' - 在前一个没有结束之前,每个进程都不会启动,你不需要任何信号量或锁。例如,如果您将 time.sleep(1) 放在函数中 - 您需要等待 500 秒才能结束。
    • 是的,抱歉,我弄错了缩进。基本上,将连接放在循环之外。现在所有进程都已启动,并在打印值之前加入。最初的问题是它没有等待每个进程都完成才能打印输出,它只是等待它开始。最后几个过程在打印输出之前不会完成。添加“p.join()”允许在打印之前等待所有进程完成。
    • 明天试试,顺便说一句!