python 学习第二十四天(同步对象、信息量、queue库)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CZ505632696/article/details/81871158
  • 同步对象
import threading,time
class Boss(threading.Thread):
    def run(self):
        print("BOSS:今晚大家都要加班到22:00。")
        print(event.isSet())
        event.set()# set flag
        time.sleep(5)
        print("BOSS:<22:00>可以下班了。")
        print(event.isSet())
        event.set()
class Worker(threading.Thread):
    def run(self):
        event.wait() #等待event的flag被set,才执行下面的代码
        print("Worker:哎……命苦啊!")
        time.sleep(1)
        event.clear()#还原到flag没有被set的状态 
        event.wait()
        print("Worker:OhYeah!")
if __name__=="__main__":
    event=threading.Event()#创建一个同步对象
    threads=[]
    for i in range(5):
        threads.append(Worker())
    threads.append(Boss())
    for t in threads:
        t.start()
    for t in threads:
        t.join()
  • 信息量
    信号量用来控制线程并发数的,BoundedSemaphore或Semaphore管理一个内置的计数 器,每当调用acquire()时-1,调用release()时+1。计数器不能小于0,当计数器为 0时,acquire()将阻塞线程至同步锁定状态,直到其他线程调用release()。(类似于停车位的概念)BoundedSemaphore与Semaphore的唯一区别在于前者将在调用release()时检查计数器的值是否超过了计数器的初始值,如果超过了将抛出一个异常。
import threading,time
class myThread(threading.Thread):
    def run(self):
        if semaphore.acquire():
            print(self.name)
            time.sleep(5)
            semaphore.release()
if __name__=="__main__":
    semaphore=threading.Semaphore(5)
    thrs=[]
    for i in range(100):
        thrs.append(myThread())
    for t in thrs:
        t.start()
  • 队列
创建一个“队列”对象
import Queue
q = Queue.Queue(maxsize = 10)
Queue.Queue类即是一个队列的同步实现。队列长度可为无限或者有限。可通过Queue的构造函数的可选参数maxsize来设定队列长度。如果maxsize小于1就表示队列长度无限。

将一个值放入队列中
q.put(10)
调用队列对象的put()方法在队尾插入一个项目。put()有两个参数,第一个item为必需的,为插入项目的值;第二个block为可选参数,默认为
1。如果队列当前为空且block为1,put()方法就使调用线程暂停,直到空出一个数据单元。如果block为0,put方法将引发Full异常。

将一个值从队列中取出
q.get()
调用队列对象的get()方法从队头删除并返回一个项目。可选参数为block,默认为True。如果队列为空且block为True,
get()就使调用线程暂停,直至有项目可用。如果队列为空且block为False,队列将引发Empty异常。

Python Queue模块有三种队列及构造函数:
1、Python Queue模块的FIFO队列先进先出。   class queue.Queue(maxsize)
2、LIFO类似于堆,即先进后出。               class queue.LifoQueue(maxsize)
3、还有一种是优先级队列级别越低越先出来。        class queue.PriorityQueue(maxsize)

此包中的常用方法(q = Queue.Queue()):
q.qsize() 返回队列的大小
q.empty() 如果队列为空,返回True,反之False
q.full() 如果队列满了,返回True,反之False
q.full 与 maxsize 大小对应
q.get([block[, timeout]]) 获取队列,timeout等待时间
q.get_nowait() 相当q.get(False)
非阻塞 q.put(item) 写入队列,timeout等待时间
q.put_nowait(item) 相当q.put(item, False)
q.task_done() 在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号。
q.join() 实际上意味着等到队列为空或者收到task_done()发送的信号,再执行别的操作
复制代码

import queue

#先进后出

q=queue.LifoQueue()

q.put(34)
q.put(56)
q.put(12)

#优先级
# q=queue.PriorityQueue()
# q.put([5,100])
# q.put([7,200])
# q.put([3,"hello"])
# q.put([4,{"name":"alex"}])

while 1:

  data=q.get()
  print(data)
  • 生产者消费者模型
import threading,time,queue,random
q=queue.Queue(maxsize=10)
count=1

def producer(name):
    global count
    while count<41:

        time.sleep(random.randint(3,5))
        print('%s生成了%d号包子\n'%(name,count))
        q.put(count)
        q.task_done()# 可以把这行注释掉,看看是什么情况
        count+=1


def client(name):
    count=1
    n=random.randint(4,10)
    while count<=n:
        q.join()
        i=q.get()
        time.sleep(1)
        print('%s:吃了%d号包子'%(name,i))
        print('这是%s吃的第%d个包子\n'%(name,count))
        count+=1




p1=threading.Thread(target=producer,args= ('A'))
p2=threading.Thread(target=producer,args=('B',))


p1.start()
p2.start()


for i in range(5):
    c = threading.Thread(target=client, args=(''.join(('消费者','(',str(i+1),')')),))
    c.start()

猜你喜欢

转载自blog.csdn.net/CZ505632696/article/details/81871158