抢票小程序优化:

 

 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 是把所有的子进程变成了串行
 
 
 # 为了保证数据的安全,串行牺牲掉效率.
 

在原来的基础上添加程序锁,使购票函数变为串行。保证程序的安全性。

队列:

情况一

 from multiprocessing improt Process, Queue
 q = Queue()
 q.put(1)
 q.put(2)
 q.put(3)
 print(q.get())
 print(q.get())
 如果输入值多,取出的值少,会一直等待取出
 

情况二

 from multiprocessing improt Process, Queue
 q = Queue(2)
 q.put(1)
 q.put(2)
 
 q.put(3) 当确定完输入值得个数,多输入的会被阻塞

情况三

 from multiprocessing improt Process, Queue
 q = Queue(2)
 q.put(1, block=True,timeout=2)
 q.put(2, block=True,timeout=2)
 
 q.put(3, block=True,timeout=5) put里的  block=True 如果满了会等待,timeout最多等待n s,如果ns后队列还是满的就报错了

情况四

 from multiprocessing improt Process, Queue
 q = Queue()
 q.put(1)
 q.get()
 
 q.gett(block=True,timeout=5) block=True 阻塞等待,timeout最多等5s, 如果5s后队列还是满的就报错了

情况五

 在情况三和情况四中将block=False,
 情况三如果队列满了就直接报错;
 情况四中拿不到不阻塞,直接报错.

情况六

 from multiprocessing improt Process, Queue
 improt time
 q = Queue(1)
 q.put('123')
 q.get()
 q.put_nowait('666')  # block = False
 time.spleep(1)
 q.get_nowait()  # block = False

生产者消费者模型:

生产者: 生产数据的任务

消费者: 处理数据的任务

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

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

补充: queue不适合传大文件,通产传一些消息.

 '''
 生产者: 生产数据的任务
 消费者: 处理数据的任务
 
 生产者--队列(盆)-->消费者
 
 生产者可以不停的生产,达到了自己最大的生产效率,消费者可以不停的消费,也达到了自己最大的消费效率.
 生产者消费者模型大大提高了生产者生产的效率和消费者消费的效率.
 
 
 # 补充: queue不适合传大文件,通产传一些消息.
 '''
 
 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() # 分析
     # 生产者生产完毕--这是主进程最后一行代码结束--q.join()消费者已经取干净了,没有存在的意义了.
     #这是主进程最后一行代码结束,消费者已经取干净了,没有存在的意义了.守护进程的概念.
 
 

JoinableQueue

 from multiprocessing import Process,Queue,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

初识别线程:

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

操作系统 ===> 工厂

进程 ===> 车间

线程 ===> 流水线

cpu ===> 电源

线程:cpu最小的执行单位

进程:资源集合/资源单位.

线程运行 = 运行代码

进程运行 = 各种资源 + 线程

posted on 2019-09-16 22:03  luelue  阅读(316)  评论(0编辑  收藏  举报