Python之进程+线程+协程(同步对象、信号量、队列)


本篇是关于Python进程方面的内容了,主要是Event同步对象,信号量和队列

Event同步对象

1、概念:
我们可以对一个线程set一个值来等待,在等待期间,其他线程都不能继续往下执行,直到这个值被clear,其他的线程才能接着往下执行

就比如考试,监考老师进入教室,一群学生开始考试;
然后只有老师说停笔,你才能够走出考场;
即使你卷子已经做完了,也得等着老师的通知才能离开。

2、测试代码:

import threading,time

#老师类
class Teacher(threading.Thread):
    def run(self):
        print("老师:开始考试,今天考到12:30!")
        print(event.isSet())  #查看是否有设置值

        #开始设置值
        event.set()  
        time.sleep(5)  #设置标准考试时间为5秒钟

        #老师的动作
        print("老师:12:30到了,考试结束!")
        #老师的动作结束了,所以再次查看是否设置了值还是False
        
        print(event.isSet())  #再次查看是否设置了值
        
        event.set()

#学生类      
class Student(threading.Thread):
    def run(self):
        event.wait()
        print("学生:唉,开考了......")
        time.sleep(1)  #假设学生考试只花1秒中
        event.clear()  #清除
        event.wait()
        print("学生:终于考完了......")
        
if __name__=="__main__":
    #实例化一个Event对象
    event=threading.Event()
    L= []
    
    for i in range(5):
        L.append(Student())
        
    L.append(Teacher())

    #启动线程
    for t in L:
        t.start()
    for t in L:
        t.join()

3、测试结果:
同步对象
可以看到,几个学生同时开考,等老师这个任务结束后,这群学生才可以结束

semaphore信号量

1、引用概念:

信号量用来控制可以同时开启线程的个数,BoundedSemaphore或Semaphore管理一个内置的计数 器,每当调用acquire()时-1,调用release()时+1。

计数器不能小于0,当计数器为 0时,acquire()将阻塞线程至同步锁定状态,直到其他线程调用release()。(类似于停车位的概念)

BoundedSemaphore与Semaphore的唯一区别在于前者将在调用release()时检查计数器的值是否超过了计数器的初始值,如果超过了将抛出一个异常。

2、测试代码:

import threading,time

#继承线程的类
class MyThread(threading.Thread):
    def run(self):
        if semaphore.acquire():
            print(self.name)  #输出线程名
            time.sleep(5)  #睡5秒,每一个线程都会停留5秒

            #释放信号量
            semaphore.release() 
            
if __name__=="__main__":
    #设置信号量,为5表明可以一次性执行的线程是5个
    semaphore=threading.Semaphore(5)
    L= []
    
    for i in range(100):
        L.append(MyThread())
        
    for t in L:  #启动线程
        t.start()

3、测试结果:
信号量
可以看到,线程每五个五个得出来

队列

1、先进先出型:

import queue  #导入线程队列

L= []

#创建线程队列对象
q= queue.Queue(5)
#能装5个对象的队列(不指定,则任意大小),block=False表示队列满了会提示错误信息

#在线程队列放入值
q.put([1,233333])
q.put([2,'little girl'])
q.put([3,{'name':'初音'}])
#q.put({'name2':'初音2'})

#取值
while True:
    data= q.get(block=True)
    #block=False表示如果卡住了会提示错误,
    #因为该线程队列已经没有数据可以取了,所以会提示队列空的信息
    print(data,'------')

先进先出

2、先进后出型:

import queue

#后进先出队列
q= queue.LifoQueue()

#在线程队列放入值
q.put([1,233333])
q.put([2,'little girl'])
q.put([3,{'name':'初音'}])

#取值
while True:
    data= q.get(block=False)
    #block=False表示如果卡住了会提示错误,
    #因为该线程队列已经没有数据可以取了,所以会提示队列空的信息
    print(data,'-----')


队列的其他方法
import queue

#创建队列
q= queue.Queue()

#在线程队列放入值
q.put([1,233333])
q.put([2,'little girl'])
q.put([3,{'name':'初音'}])

#取值
print(q.qsize())  #队列值的个数
print(q.empty())  #是否为空
print(q.full())  #是否满
q.task_done()

先进后出

猜你喜欢

转载自blog.csdn.net/Viewinfinitely/article/details/105473250
今日推荐