python队列

Posted jhpy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python队列相关的知识,希望对你有一定的参考价值。

优化抢票

加入Lock

lock.acquire() 锁住
lock.release()释放锁头

  • 进程锁把所著的代码编程串行,
  • join 是把所有的子进程变成了串行。
from  multiprocessing import Process,Lock
import json,time,os

def search():
    time.sleep(1) # 模拟网络io
    with open('db.txt',mode='rt',encoding='utf-8') as f:
        res = json.load(f)
        print(f'还剩res["count"]')

def get():
    with open('db.txt',mode='rt',encoding='utf-8') as f:
        res = json.load(f)
        # print(f'还剩res["count"]')
    time.sleep(1) # 模拟网络io
    if res['count'] > 0:
        res['count'] -= 1
        with open('db.txt',mode='wt',encoding='utf-8') as f:
            json.dump(res,f)
            print(f'进程os.getpid() 抢票成功')
        time.sleep(1.5) # 模拟网络io
    else:
        print('票已经售空啦!!!!!!!!!!!')

def task(lock):
    search()

    # 锁住
    lock.acquire()
    get()
    lock.release()
    # 释放锁头

if __name__ == '__main__':
    lock = Lock() # 写在主进程是为了让子进程拿到同一把锁.
    for i in range(15):
        p = Process(target=task,args=(lock,))
        p.start()
        # p.join()

    #  进程锁 是把锁住的代码变成了串行
    #  join 是把所有的子进程变成了串行


# 为了保证数据的安全,串行牺牲掉效率.

队列

  • ipc机制 进程通讯
  • 管道:pipe 基于共享的内存空间
  • 队列:pipe+锁 queue

==put()==放东西

get.()拿东西,如果拿的东西拿多了那么,就会一直等着拿值,不会报错

Queue() 队列满了,再放值就会阻塞。
block为阻塞状态,True 默认阻塞状态是对的,满了就会阻塞,False就是错的,则会抛错

block=True 如果满了会等待,

timeout=n,n秒后如果队列中还是满的就会报错

Queue不适合传大的文件

生产者消费者模型

JoinableQueue()

task_done()先放对队列一个任务,然后完成了一次任务#向q.join()发送一次信号,证明一个数据已经被取走了

q=JoinableQueue()

q.join() #计数器不为0的时候,阻塞等待计数器为0后通过

包子的故事 简单的提高生产者生产效率和消费者消费效率,生产者

'''
生产者: 生产数据的任务                                    

生产者--队列(盆)-->消费者

生产者可以不停的生产,达到了自己最大的生产效率,消费者可以不停的消费,也达到了自己最大的消费效率.
生产者消费者模型大大提高了生产者生产的效率和消费者消费的效率.


# 补充: queue不适合传大文件,通常传一些消息.
'''
from multiprocessing import Process,Queue
def producer (q,name,food):
    for i in range(10):
        print(f'name生产了foodi')
        time.sleep(random.randint(1,3))
        res=f'foodi'
        q.put(res)
        
def consumer(q,name):
    #消费者
    while True:
        res=q.get()
        print(f'name吃了res')
        q.task_done()
        
if __name__ =='__main__':
    q=JoinableQueue()
    p1 = Process(target=producer,args=(q,'rocky','包子'))
    p2 = Process(target=producer,args=(q,'mac','韭菜'))
    p3 = Process(target=producer,args=(q,'nick','蒜泥'))
    c1 = Process(target=consumer,args=(q,'成哥'))
    c2 = Process(target=consumer,args=(q,'浩南哥'))
    c1.daemon=True
    c2.daemon=True
    p_lst=[p1,p2,p3,c1,c2]
    for p in p_lst:
        p.start()       
    p1.join()
    p1.join()
    p2.join()
    p3.join() # 生产者生产完毕
    # q.put(None)# 几个消费者put几次
    # q.put(None)
    q.join() # 分析
    # 生产者生产完毕--这是主进程最后一行代码结束--q.join()消费者已经取干净了,没有存在的意义了.
    #这是主进程最后一行代码结束,消费者已经取干净了,没有存在的意义了.守护进程的概念.    
        

以上是关于python队列的主要内容,如果未能解决你的问题,请参考以下文章

Python 线程优先队列 PriorityQueue

Python队列的三种队列方法

python3的队列,比python2更好

Python实现栈队列

队列-Python 实现

python队列