Python高级(15)—多线程、多进程同步之Semaphore

◎知识点

  1. 多线程同步之Semaphore

  2. 多进程同步之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

Python高级(15)—多线程、多进程同步之Semaphore


▽ 多进程同步之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


◎脚本地址:https://github.com/anzhihe/learning/blob/master/python/practise/learn-python/python_senior/semaphore.py

anzhihe 安志合个人博客,版权所有 丨 如未注明,均为原创 丨 转载请注明转自:https://chegva.com/5626.html | ☆★★每天进步一点点,加油!★★☆ | 

您可能还感兴趣的文章!

发表评论

电子邮件地址不会被公开。 必填项已用*标注