Python高级培训第四次作业

'''使用类继承的方式,实现信号量、事件功能操作。
具体案例:第一个线程中获取当前时间,判断当前时间3秒之后,触发“事件”对象。
在另一个线程中,作为数学考试结束的判断变量,否则一直处于考试中,并打印。'''
import threading#导入库threading,time
import time
event = threading.Event()#先创建一个event 方便下面使用
event.set()#设置event默认为True
class Get_time(object): #创建类Get_time来获取时间 判断时间
    def __init__(self,start_time):#获取一个初始时间
        self.start_time=start_time
    def give_time(self,time0):#创建方法 来判断 当时间为3秒时 event设置为False
        while True:
            if time.time()-time0<3:
                print(time.time()-time0)
                time.sleep(0.5)
                event.set()
            else:
                event.clear()
                break
class Kaoshi(object):#创建类Kaoshi来进行考试 当event设置为False时考试结束 否则一直打印正在考试
    def print_kaoshi(self,n,semaphore):
        while True:
            time.sleep(0.1)
            if event.is_set():
                semaphore.acquire()#获取semaphore来实现多个位置同时运行
                print("考生{0}正在考试".format(n))
                semaphore.release()
            else:
                print("考试结束")
                break

class Start_kaoshi(Get_time,Kaoshi):#创建类Start_kaosh来总执行 继承Get_time,Kaoshi
    def __init__(self,start_time):
        Get_time.__init__(self,start_time)#调用 Get_time的init
        Kaoshi.__init__(self)#调用 Kaoshi的init
    def Start(self):#设置方法 来实现总开关
        semaphore=threading.Semaphore(3)#创建3个semaphore
        thread2 = threading.Thread(target=self.give_time, args=(self.start_time,))#先创建控制时间的线程
        thread2.start()
        time.sleep(0.1)
        for i in range(3):#创建3个考试的线程
            t=threading.Thread(target=self.print_kaoshi,args=(i,semaphore))
            t.start()
time_start=time.time()#获取初始时间
c1=Start_kaoshi(time_start)#实例化c1
c1.Start()#考试开始

信号量

信号量可以让程序允许固定的线程数

threading.Semaphore(thread_number)

semaphore=threading.Semaphore(3)#设置信号量有3个(最多同时运行3个线程)

semaphore.acquire()#获得一个信号量

semaphore.release()#释放信号量

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

条件变量:

条件变量是在lock的基础上进行的完善,相比lock有更多的功能,可以锁的同时,可以设置等待的时间(wait),并可以通知(notify)来取消等待。

threading.Condition()

acquire(timeout)

调用Condition类关联的Lock/RLock的acquire()方法。

release()

调用Condition类关联的Lock/RLock的release()方法。

wait(timeout)

1)线程挂起,直到收到一个notify通知或者等待时间超出timeout才会被唤醒;

2)注意:wait()必须在已获得Lock的前提下调用,否则会引起RuntimeError错误。

notify(n=1)

1)唤醒在Condition的waiting池中的n(参数n可设置,默认为1)个正在等待的线程并通知它,受到通知的线程将自动调用acquire()方法尝试加锁;

2)如果waiting池中有多个线程,随机选择n个唤醒;

3)必须在已获得Lock的前提下调用,否则将引发错误。

notify_all()

唤醒waiting池中的等待的所有线程并通知它们

import threading
def run(x):
    con.acquire()
    print("线程{0}".format(x))
    print("线程{0}挂起".format(x))
    con.notify(1)#通过注释这一行可以看到区别
    con.wait(5)
    print("线程{0}再次气动".format(x))
    con.release()
if __name__=="__main__":
    con=threading.Condition()
    for i in range(50):
        a=threading.Thread(target=run,args=(i,))
        a.start()

事件

事件可以控制所有的线程,让所有的线程同时去等待/运行

threading.Event()

event=threading.Event()#这一行一定要放前面 血的教训 这样作为全局变量才能直接被用

event.wait(timeout=None):

调用该方法的线程会被阻塞,如果设置了timeout参数,超时后,线程会停止阻塞继续执行;event.set():

将event的标志设置为True,调用wait方法的所有线程将被唤醒;

event.clear():

将event的标志设置为False,调用wait方法的所有线程将被阻塞;

event.is_set():判断event的标志是否为True。

例子:

import time, threading
event = threading.Event()
# 交通灯
def lighter():
    count = 0
    while True:
        if count < 5:  # 绿灯
            event.set()  #设置标志位
            print("\033[42;1m 绿灯亮\033[0m")
        elif count > 10:
            count =0  # 清零重新计数
        else:  # 红灯
            event.clear()  # 清空标志位
            print("\033[41;1m 红灯亮\033[0m")

        time.sleep(1)
        count += 1

# 车辆
def car(name):
    while True:
        if event.is_set():  # 绿灯亮
            print("[%s]绿灯行..." % name)
            time.sleep(1)
        else:
            print("[%s]红灯停!!!" % name)
            event.wait()  # 等待标志位设定
            print("\033[34;1m绿灯出发\033[0m")

# 启动交通灯
t_lighter = threading.Thread(target=lighter)
t_lighter.start()

# 放入车辆
t_car1 = threading.Thread(target=car, args=("奥迪车",))
t_car2 = threading.Thread(target=car, args=("大众车",))
t_car1.start()
t_car2.start()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值