Python的信号量永远挂起

1 投票
2 回答
1258 浏览
提问于 2025-04-17 23:33

我在我的程序里想要同时做一些事情,并且限制同时打开的进程数量(最多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个“new”和“done”),然后就没了。我没有看到其他的“new”,程序就卡在那儿了(Ctrl-C也没用)。这是怎么回事呢?

2 个回答

0

你的有界信号量在不同的进程之间没有正确共享;你可能需要考虑使用 multiprocessing.BoundedSemaphore。想了解更多细节,可以看看 这个问题 的回答。

2

你的问题在于使用了 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._value 替换成 semaphore.get_value(),你会看到上面的输出发生变化。)

撰写回答