信号量、条件变量、事件

导读:本篇文章讲解 信号量、条件变量、事件,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

信号量(Semaphore)

        threading模块里的Semaphore类实现了信号量对象,可用于控制获取资源的线程数量。所具有的acquire()和release()方法,可以用with语句的上下文管理器。当进入时,将调用acquire()方法,当退出时,将调用release()。

        Semaphore跟Lock类似,但是Semaphore可以允许指定最多多少个进程访问资源。就像该资源有多个门,每个门一把锁。一个进程访问了资源,锁了门,还有其他门可以使用。但是如果所有门都被使用了,那么就得等待有进程出来释放锁才可以。

信号量、条件变量、事件

 

'''信号量'''
import threading
import time

def run(n):
    semaphore.acquire()
    print("线程:",n)
    time.sleep(1)
    semaphore.release()

if __name__ == '__main__':
    #设置信号量
    semaphore = threading.Semaphore(2)#每2个同时执行
    for i in range(5):
        t = threading.Thread(target=run,args=(i,))
        t.start()

运行结果:

线程:0线程:1

线程:2线程:3

线程:4线程:5

线程:6线程:7

线程:8线程:9

条件变量(Conditional variable)

        Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还提供了wait和notify方法。线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则wait;如果条件满足,进行一些处理改变条件后,通过notify方法唤醒其他线程,其他处于wait状态的线程接到唤醒后会重新判断条件。不断的重复这一过程,从而解决复杂的同步问题。

'''条件变量'''
import threading
import time

def run(n):
    con.acquire()
    print(f'线程:{n}')
    con.notify()#启动该线程时唤醒其他线程启动
    print(f'线程:{n}挂起')
    con.wait()#令其等待
    time.sleep(1)
    print(f'线程:{n}再次启动')
    con.notify()
    con.release()

#同时运行
if __name__ == '__main__':
    con = threading.Condition()#条件变量
    for i in range(10):
        t = threading.Thread(target=run,args=(i,))
        t.start()
线程:0
线程:0挂起
线程:1
线程:1挂起
线程:0再次启动
线程:2
线程:2挂起
线程:3
线程:3挂起
线程:4
线程:4挂起
线程:5
线程:5挂起
线程:6
线程:6挂起
线程:5再次启动
线程:8
线程:8挂起
线程:9
线程:9挂起
线程:1再次启动
线程:2再次启动
线程:3再次启动
线程:4再次启动
线程:7
线程:7挂起
线程:6再次启动
线程:8再次启动
线程:9再次启动

事件(Event)

        Python提供了Event对象用于线程间通信,它是由线程设置的信号标志,如果信号标志位真,则其他线程等待直到信号接触。事件对象可以通过通知操作的方式来保持线程的同步,并且可以实现不同进程中的线程同步操作。

        Event对象实现了简单的线程通信机制,它提供了设置信号set(),清除信号clear(),等待wait()等用于实现线程间的通信。

'''事件'''
import threading
import time
def car():
    #死循环,让其检测事件是否被设置
    while True:
        if event.is_set():#如果事件被设置
            print('小车行驶')
        else:
            print('小车停止')
            event.wait()#如果事件被清除则wait

def set_event():
    #死循环,一直让其设置/取消事件
    while True:
        event.set()#设置事件
        time.sleep(1)  #在这1秒内会重复打印'小车行驶',因为线程car1一直在检测
        event.clear()  #清除事件
        time.sleep(1)  #在这1秒内不会重复打印,因为线程car1在wait
        #随后循环到开头,事件继续被设置,继续打印‘小车行驶’

if __name__ == '__main__':
    event = threading.Event()
    #线程启动,两个线程同时进行
    car1 = threading.Thread(target=car)
    car1.start()
    set1 = threading.Thread(target=set_event)
    set1.start()

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99498.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!