• day 37 用进程锁优化抢票程序、队列、生产者消费者模型、线程的初步认识



    用进程锁优化抢票程序
    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


    from multiprocessing import Process,Queue

    # 案例一
    q = Queue()
    q.put('鲁照山')
    q.put([1,2,4])
    q.put(2)
    print(q.get())
    print(q.get())
    print(q.get())
    # q.put(5)
    # q.put(5)
    print(q.get()) # 默认就会一直等着拿值



    # 案例2
    q = Queue(4)
    q.put('鲁照山')
    q.put([1,2,4])
    q.put([1,2,4])
    q.put(2)

    q.put('乔碧萝') #队列满了的情况再放值,会阻塞


    # 案例3 (从这往下都是了解)
    q = Queue(3)
    q.put('zhao',block=True,timeout=2) #
    q.put('zhao',block=True,timeout=2) #
    q.put('zhao',block=True,timeout=2) #

    q.put('zhao',block=True,timeout=5) # put里的 block=True 如果满了会等待,timeout最多等待n s,如果ns还是队列还是满的就报错了

    # 案例4
    q = Queue()
    q.put('yyyy')
    q.get()
    q.get(block=True,timeout=5) # get里的 block=True 阻塞等待,timeout最多等5s, 剩下同上

    # 案例5
    q = Queue(3)
    q.put('qwe')
    q.put('qwe')
    q.put('qwe')

    q.put('qwe',block=False) # 对于put来说block=False 如果队列满了就直接报错

    q = Queue(3)
    q.put('qwe')
    q.get()


    q.get(block=False)
    block = Flase 拿不到不阻塞,直接报错

    # 案例6
    q = Queue(1)
    q.put('123')
    # q.get()
    q.put_nowait('666') # block = False
    # q.get_nowait() # block = False




    生产者消费者模型
    '''
    生产者: 生产数据的任务
    消费者: 处理数据的任务

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

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


    # 补充: queue不适合传大文件,通产传一些消息.
    '''
    from multiprocessing import Process,Queue
    import time,random

    def producer(q,name,food):
    '''生产者'''
    for i in range(3):
    print(f'{name}生产了{food}{i}')
    time.sleep(random.randint(1, 3))
    res = f'{food}{i}'
    q.put(res)
    # q.put(None)

    def consumer(q,name):
    '''消费者'''
    while True:
    res = q.get(timeout=5)
    if res is None:break
    time.sleep(random.randint(1,3))
    print(f'{name}吃了{res}')

    if __name__ == '__main__':
    q = Queue()
    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,'浩南哥'))
    p1.start()
    p2.start()
    p3.start()
    c1.start()
    c2.start()
    p1.join()
    p2.join()
    p3.join() # 生产者生产完毕
    q.put(None)# 几个消费者put几次
    q.put(None)
    #通过返回none 终止消费者进程





    joinablequeue:
    from multiprocessing import JoinableQueue

    q = JoinableQueue()
    q.put('zhao') # 放队列里一个任务
    q.put('qian')
    print(q.get())
    q.task_done() # 完成了一次任务
    print(q.get())
    q.task_done() # 完成了一次任务
    q.join() #计数器不为0的时候 阻塞等待计数器为0后通过
    # 想象成一个计数器 :put +1 task_done -1



    from multiprocessing import Process,Queue,JoinableQueue
    import time,random

    def producer(q,name,food):
    '''生产者'''
    for i in range(3):
    print(f'{name}生产了{food}{i}')
    time.sleep(random.randint(1, 3))
    res = f'{food}{i}'
    q.put(res)
    # q.put(None)

    def consumer(q,name):
    '''消费者'''
    while True:
    res = q.get()
    # if res is None:break
    time.sleep(random.randint(1,3))
    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,'浩南哥'))
    p1.start()
    p2.start()
    p3.start()
    c1.daemon = True
    c2.daemon = True
    c1.start()
    c2.start()
    p1.join()
    p2.join()
    p3.join() # 生产者生产完毕
    # q.put(None)# 几个消费者put几次
    # q.put(None)
    q.join() # 分析
       #加入守护进程和joinableque
    # 生产者生产完毕--这是主进程最后一行代码结束--q.join()消费者已经取干净了,没有存在的意义了.
    #这是主进程最后一行代码结束,消费者已经取干净了,没有存在的意义了.守护进程的概念.



    线程的初步认识

    ''' 初识别线程. 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 在工厂中, 每个车间都有房子,而且每个车间默认就有一条流水线.

    操作系统 ===> 工厂 进程 ===> 车间 线程 ===> 流水线 cpu ===> 电源

    线程:cpu最小的执行单位 进程:资源集合/资源单位. 线程运行 = 运行代码 进程运行 = 各种资源 + 线程

    '''

     

     

     


  • 相关阅读:
    ssh登录很慢的问题
    Y480&Y580 刷slic2.1全自动教程
    re正则表达式5_*
    linux下查看内存使用情况
    检查linux网络的状况
    Linux Load average负载详细解释
    查看Linux磁盘空间大小
    Linux 批量重命名文件
    Linux 网卡丢包严重
    linux 下vi /vim 中文汉字乱码解决
  • 原文地址:https://www.cnblogs.com/wwei4332/p/11527558.html
Copyright © 2020-2023  润新知