【问题标题】:Process synchronization in PythonPython中的进程同步
【发布时间】:2013-05-21 21:48:37
【问题描述】:

我尝试使用信号量来同步多个进程。我认为不是为每个进程创建一个函数,而是可能以更通用的方式使用单个函数和一些依赖项的参数:

import multiprocessing
from multiprocessing import *

class Worker:
    def __init__(self, size):
        self._semaphores = [Semaphore(0)]*(size + 1)

    def run(self, name, acquire, release):
        for i in acquire:
            self._semaphores[i].acquire()

            print('Running', name)

        for i in release:
            self._semaphores[i].release()

在这种情况下,我有五个进程。第一个先开始,第二个和第三个在第一个之后,第四个在第二个和第三个之后,第五个在第四个之后。

if __name__ == '__main__':
    worker = Worker(5)
    Process(target=worker.run, args=('5', [5], [])).start()
    Process(target=worker.run, args=('4', [4,4], [5])).start()
    Process(target=worker.run, args=('3', [3], [4])).start()
    Process(target=worker.run, args=('2', [2], [4])).start()
    Process(target=worker.run, args=('1', [], [2,3])).start()

预期的输出是:

Running 1
Running 2
Running 3
Running 4
Running 5

但是同步没有按预期工作。执行是随机的,包括死锁。这是为什么呢?

【问题讨论】:

    标签: python multiprocessing semaphore synchronisation


    【解决方案1】:

    [Semaphore(0)]*(size + 1) 创建一个列表,其中 size + 1 引用 single Semaphore 对象。您需要为该类创建不同的实例:

    self._semaphores = [Semaphore(0) for _ in range(size + 1)]
    

    【讨论】:

    • 非常感谢,这绝对是正确的!但有一件小事我不明白。固定版本不会强制执行预期的顺序。所以输出仍然是随机的,但在 Windows 系统上没有死锁。有什么想法吗?
    • @witrin:我不完全确定您为什么需要信号量。为什么不创建一个进程池并使用pool.map_sync 将结果按顺序返回?
    • 因为它是需要使用信号量的练习的一部分。
    • 看来,固定代码在 Windows 上不起作用,在 Linux 上就没有问题了。谢谢!
    【解决方案2】:

    打印的缩进不正确,这会阻止 ('Running', '1')。搞定后,1打印,然后2和3混合,然后4,然后5。2和3是混合的,因为它们是一起踢出来的,所以操作符合预期。

    【讨论】:

      猜你喜欢
      • 2014-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-02
      相关资源
      最近更新 更多