【问题标题】:Python's semaphore hangs for everPython 的信号量永远挂起
【发布时间】:2014-03-23 20:20:13
【问题描述】:

我试图在我的程序中同时做一些事情并限制同时打开的进程数 (10)。

from multiprocessing import Process
from threading import BoundedSemaphore

semaphore = BoundedSemaphore(10)
for x in xrange(100000):
  semaphore.acquire(blocking=True)
  print 'new'
  p = Process(target=f, args=(x,))
  p.start()

def f(x):
  ...  # do some work
  semaphore.release()
  print 'done'

前 10 个进程启动并正确结束(我在控制台上看到 10 个“新”和“完成”),然后什么也没有。我没有看到另一个“新”,程序只是挂在那里(而且 Ctrl-C 也不起作用)。怎么了?

【问题讨论】:

  • 为什么不直接使用multiprocessing.Pool
  • 是什么让您认为threading.BoundedSemaphorerelease 会跨越进程边界?
  • @Thanatos 信号量是一个全局对象,acquire 应该是阻塞的,如文档中所述;我错过了什么吗?
  • @g.d.d.c 注意到,我试过了,我很满意,但我仍然想知道为什么这不起作用

标签: python multithreading semaphore


【解决方案1】:

您的问题是跨进程边界使用threading.BoundedSemaphore

import threading
import multiprocessing
import time

semaphore = threading.BoundedSemaphore(10)


def f(x):
  semaphore.release()
  print('done')


semaphore.acquire(blocking=True)
print('new')
print(semaphore._value)
p = multiprocessing.Process(target=f, args=(100,))
p.start()
time.sleep(3)
print(semaphore._value)

当您创建一个新进程时,子进程会获得父进程内存的副本。因此,孩子正在减少它的信号量,而父母中的信号量没有受到影响。 (通常,进程是相互隔离的:跨进程通信需要一些额外的工作;这就是 multiprocessing 的用途。)

这与线程相反,两个线程共享内存空间,并被视为同一个进程。

multiprocessing.BoundedSemaphore 可能是你想要的。 (如果你用它替换threading.BoundedSemaphore,然后用semaphore.get_value() 替换semaphore._value,你会看到上面的输出变化。)

【讨论】:

    【解决方案2】:

    您的有界信号量未在正在生成的各个进程之间正确共享;你可能想改用multiprocessing.BoundedSemaphore。有关更多详细信息,请参阅this question 的答案。

    【讨论】:

    • 我看到这个问题一开始似乎有所不同。现在有了答案,我看到他也使用了threading. 而不是multiprocessing. 这就是他问这个问题的原因
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    相关资源
    最近更新 更多