Python:Day29 信号量、条件变量

信号量:semaphore

信号量是用来控制线程并发数的。(理解:虽然GIL任意时刻都只有一个线程被执行,但是所有线程都有资格去抢,semaphore就是用来控制抢的GIL的数量,只有获取了semaphore的线程才有资格去抢GIL,起到了限制线程并发数的作用)

import threading
import time


class MyThread(threading.Thread):
    def run(self):
        if semap.acquire():
            print(semap)
            print(self.name)
            time.sleep(5)
            semap.release()


semap = threading.Semaphore(5)  # 括号内如果没有指定数据,默认为1

thrs = []

for i in range(100):
    thrs.append(MyThread())
for i in thrs:
    i.start()

semaphore也是一把锁,这把锁内部有一个计数器,被acquire()的时候-1,release()的时候+1,当计数器为0的时候,其它线程将被阻塞。

semaphore和RLock都可以被重复获取,也都有计数器,区别是:semaphore是被不同线程获取,而RLock只能被同一线程重复获取。

条件变量:不仅能实现锁的功能,而且能够实现类似线程间的通信功能

用于一个标志符来实现线程间通信

threading.Condition([Lock/Rlock]):锁是可选选项,不传入锁,对象自动创建一个Rlock(0

wait():条件不满足时调用,线程会释放锁并进入等待阻塞

notify():条件创造后调用,通知等待池激活一个线程

notifyAll():条件创造后调用,通知等待池激活所有线程

import threading
from random import randint
import time


class Producer(threading.Thread):
    def run(self):
        global L
        while 1:
            lock_con.acquire()
            r = randint(0, 100)
            print(self.name + "已生产" + str(r))
            L.append(r)
            lock_con.notify()
            lock_con.release()
            time.sleep(1)


class Consumer(threading.Thread):
    def run(self):
        global L
        while 1:
            lock_con.acquire()
            if len(L) == 0:
                lock_con.wait()
            print("消费者吃了"+str(L[0]))
            del L[0]
            lock_con.release()


if __name__ == '__main__':
    L = []
    lock_con = threading.Condition()
    threads = []
    for i in range(5):
        threads.append(Producer())
    threads.append(Consumer())
    for i in threads:
        i.start()

要想实现两个线程之间的通信,两个线程用的必须是同一把锁,不然无法起到作用。

条件同步(Event)

条件同步和条件变量同步差不多,只是少了锁的功能,因为条件同步设计于不访问共享资源的环境。

event = threading.Event():条件环境变量,初始值为False

event.isSet():返回event的状态值
event.set():设备event的状态值为True,所有阻塞池的线程激活进入就绪状态,等待操作系统调试。
event.clear():设置event的状态值为False
event.wait():如果event的状态值为False时,阻塞线程

 实例1:

import threading
import time


class Boss(threading.Thread):
    def run(self):
        print("今晚要加班!!!!")
        event.set()
        time.sleep(5)
        print("已经10点了,可以下班了!")
        event.set()


class Work(threading.Thread):
    def run(self):
        event.wait()
        print("命苦啊!!!!")
        event.clear()
        event.wait()
        print("oh,yeah!")


if __name__ == '__main__':
    event = threading.Event()
    threads = []
    for i in range(3):
        threads.append(Work())
    threads.append(Boss())
    for i in threads:
        i.start()
    for i in threads:
        i.join()

实例2:红绿灯

import threading
import time
import random


def ligth():
    if not event.isSet():
        event.set()
    count = 0
    while 1:
        if count < 10:
            print("this light is green!")
        elif count < 13:
            print("the light is yellow!")
        elif count < 20:
            if event.isSet():
                event.clear()
            print("the light is red!")
        else:
            count = 0
            event.set()
        time.sleep(1)
        count += 1


def car(n):
    while 1:
        time.sleep(random.randrange(10))
        if event.isSet():
            print("car %s is running" % n)
        else:
            print("car %s is waiting for red light..." % n)


event = threading.Event()
Light = threading.Thread(target=ligth)
Light.start()
for i in range(3):
    t = threading.Thread(target=car,args=(i,))
    t.start()
原文地址:https://www.cnblogs.com/sq5288/p/9358062.html