Python学习4(信号量 条件变量 事件)

信号量

信号量是一个特殊的变量,它的本质是计数器,信号量里面记录了临界资源的数目,有多少数目,信号量的值就为多少,进程对其访问都是原子操作(pv操作,p:占用资源,v:释放资源)。它的作用就是,调协进程对共享资源的访问,让一个临界区同一时间只有一个进程在访问它。

  • 为什么需要使用信号量
    对于生产者来说,当缓冲区满,也就是空闲缓冲区个数为0时,此时生产者不能继续向缓冲区写数,必须等待,直到有消费者从满缓冲区取走数后,再次有了空闲缓冲区,生产者才能向缓冲区写数。
    对于消费者来说,当缓冲区空时,此时没有数可以被取走,消费者必须等待,直到有生产者向缓冲区写数后,消费者才能取走。并且如果当缓冲区空时,先后有多个消费者均想从缓冲区取数,那么它们均需要等待,此时需要记录下等待的消费者个数,以便缓冲区有数可取后,能将所有等待的消费者唤醒,确保请求取数的消费者最终都能取的数。
    也就是说,当多个进程需要协同合作时,需要根据某个信号,判断当前进程是否需要停下来等待;同时,其他进程需要根据这个信息判断是否有进程在等待,或者有几个进程在等待,以决定是否需要唤醒等待的进程。而这个信息,就是信号量。
  • 如何使用信号量
    (1)使用threading模块里的Semaphore类,实现信号量对象,控制获取资源的线程数量。
    (2)进入时,调用acquire()方法,退出时,调用release()。

import threading
import time
 
def run(n):
    semaphore.acquire()
    print(n)
    time.sleep(1)
    semaphore.release()
 
if __name__=='__main__':
    semaphore=threading.Semaphore(5)
    for i in range(50):
        t=threading.Thread(target=run,args=(i, ))
        t.start()

条件变量

条件变量是线程的另外一种同步机制,这些同步对象为线程提供了会合的场所,理解起来就是两个(或者多个)线程需要碰头(或者说进行交互-一个线程给另外的一个或者多个线程发送消息),我们指定在条件变量这个地方发生,一个线程用于修改这个变量使其满足其它线程继续往下执行的条件,其它线程则接收条件已经发生改变的信号。

条件变量同锁一起使用使得线程可以以一种无竞争的方式等待任意条件的发生。所谓无竞争就是,条件改变这个信号会发送到所有等待这个信号的线程。而不是说一个线程接受到这个消息而其它线程就接收不到了。

  • 使用条件变量
    (1)创建Condition对象,使用acquire调用Condition对象
    (2)调用wait方法时,释放Condition,进入等待状态,同时在waiting池中记录这个线程。
    (3)调用notify方法时,Condition对象调用acquire方法尝试取到锁。
import threading
import time
 
 
def run(x):
    con.acquire()
    print(f'线程{x}')
    con.notify()
    print(f'线程{x}挂起')
    con.wait()
    time.sleep(1)
    print(f'线程{x}再次启动')
    con.notify()
    con.release()
 
if __name__=='__main__':
 
    con = threading.Condition()
    for i in range(10):
        t=threading.Thread(target=run,args=(i, ))
        t.start()

事件

线程之间通信的最简单机制之一:一个线程发出事件信号,而其他线程等待该信号。用于主线程控制其他线程的执行,事件是一个简单的线程同步对象

import threading
import time
 
 
def car():
    while True:
        if event.is_set():
            print('小车行驶')
        else:
            print('小车停止')
            event.wait()
 
def set_event():
    while True:
        event.set()
        time.sleep(1)
        event.clear()
        time.sleep(1)
 
event=threading.Event()
car1=threading.Thread(target=car)
car1.start()
set_e=threading.Thread(target=set_event())
set_e.start()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值