Here我发现以下示例(这是修改后的版本)使用信号量与多处理模块:
#!/bin/env python
import multiprocessing
from time import sleep
import os
max_allowed_processes_in_critical_section=1
semaphore = multiprocessing.Semaphore(max_allowed_processes_in_critical_section)
def do_job(id):
# BEGINNING OF CRITICAL SECTION
with semaphore:
sleep(1)
print "#####################"
print "Inside locked semaphore"
print "PPID: %s" % os.getppid()
print "PID: %s" % os.getpid()
# END OF CRITICAL SECTION
print("Finished job")
def main():
pool = multiprocessing.Pool(6)
for job_id in range(6):
print("Starting job")
pool.apply_async(do_job, [job_id])
pool.close()
pool.join()
if __name__ == "__main__":
main()
正如您在此上下文中所看到的,信号量与with
关键字一起使用。通常,信号量有两种方法wait()
和signal()
。在python的threading
和multiprocessing
模块中,这些方法是AFAIK,相当于acquire()
和release()
。我已经将代码重写为使用acquire()
和release()
方法的代码:
#!/bin/env python
import multiprocessing
from time import sleep
import os
max_allowed_processes_in_critical_section=1
semaphore = multiprocessing.Semaphore(max_allowed_processes_in_critical_section)
def do_job(id):
# BEGINNING OF CRITICAL SECTION
semaphore.acquire()
sleep(1)
print "#####################"
print "Inside locked semaphore"
print "PPID: %s" % os.getppid()
print "PID: %s" % os.getpid()
semaphore.release()
# END OF CRITICAL SECTION
print("Finished job")
def main():
pool = multiprocessing.Pool(6)
for job_id in range(6):
print("Starting job")
pool.apply_async(do_job, [job_id])
pool.close()
pool.join()
if __name__ == "__main__":
main()
从我之前的question开始,我了解到当某个方法与with
关键字一起使用时,会在进入时调用上下文管理器的__enter__()
和__exit__()
方法(和分别从with
语句的正文退出。因此,我假设在acquire()
内调用__enter__()
,在release()
内调用__exit__()
。
问题:
我的假设是从acquire()
和__enter__()
调用release()
来自__exit__()
的{{1}}正确吗?
我能否以某种方式查看此示例中__enter__()
和__exit__()
方法的用途?我还注意到,当我在with
版本中访问未定义的变量时,我没有得到任何异常(必须有一些异常处理才能简单地抑制错误)。
E.G。即使ppid
和pid
不存在,这个也不会抛出异常
print "#####################"
print "Inside locked semaphore"
print "PPID: %s" % ppid
print "PID: %s" % pid
BoundedSemaphore([value])
和Semaphore([value])
嵌套在documentation的class multiprocessing.managers.SyncManager
下,你可以澄清一下吗?答案 0 :(得分:0)
with
块可以抑制异常,但信号量的块不应这样做。可能是multiprocessing
的背景下(或(或曾在2015年)有一个错误)。Semaphore
下的SyncManager
之类的名称是用于创建由管理器支持的同步对象的函数-它们像类一样被命名,以暗示它们像类一样被调用来制造新对象。