◎知识点
多线程同步之Semaphore
多进程同步之Semaphore
◎脚本练习
▽ 多线程同步之Semaphore
"""
标准库模块threading中提供了一个类对象Semaphore,用于表示信号量,它可以帮助我们控制并发线程的
最大数量,从而实现多线程之间的同步。
Semphore也遵守了上下文管理协议,所以可以使用with语句对代码进行简化。
"""
from threading import Thread, Semaphore
import time, random
sem = Semaphore(3)
class MyThread(Thread):
def run(self):
# sem.acquire()
with sem:
print('%s获得资源' % self.name)
time.sleep(random.random() * 10)
# sem.release()
for i in range(10):
MyThread().start()
"""
如果调用release()的次数比调用acquire()的次数多,计数器的当前值就会超过它的初始值。
为了确保能够及时检测到程序中的这种bug,可以使用BoundedSemaphore替代semaphore,这样,
一旦程序中出现这种bug,就会抛出异常ValueError
"""
from threading import BoundedSemaphore
bsem = BoundedSemaphore(3)
bsem.acquire()
bsem.release()
# bsem.release() # ValueError: Semaphore released too many times▽ 多进程同步之Semaphore
"""
标准库模块multiprocessing中提供了一个类对象Semaphore,用于表示信号量,它可以帮助我们控制并发进程的
最大数量,从而实现多进程之间的同步。
Semphore也遵守了上下文管理协议,所以可以使用with语句对代码进行简化。
"""
from multiprocessing import Process, Semaphore
import time, random
sem = Semaphore(3)
class MyProcess(Process):
def run(self):
# sem.acquire()
with sem:
print('%s获得资源' % self.name)
time.sleep(random.random() * 10)
# sem.release()
if __name__ == '__main__':
for i in range(10):
MyProcess().start()
"""
如果调用release()的次数比调用acquire()的次数多,计数器的当前值就会超过它的初始值。
为了确保能够及时检测到程序中的这种bug,可以使用BoundedSemaphore替代semaphore,这样,
一旦程序中出现这种bug,就会抛出异常ValueError。
但是,官方文档中提到: On Mac OS X, this is indistinguishable from Semaphore。
"""
from multiprocessing import BoundedSemaphore
bsem = BoundedSemaphore(3)
bsem.acquire()
bsem.release()
bsem.release() # 在MacOS平台没有抛出异常ValueError