博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
抢票小程序
阅读量:5291 次
发布时间:2019-06-14

本文共 2455 字,大约阅读时间需要 8 分钟。

目录

抢票小程序

version1(并发)

#db.txt{"count": 1}--------------------------------from  multiprocessing import Processimport json,time,osdef 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():    search()    get()if __name__ == '__main__':    for i in range(15):        p = Process(target=task)        p.start()---------------------------------------------并发运行效率高,但竞争写同一个文件,数据写入错乱,只有一张票,却成功卖给多个人

于是进行加锁处理

version2(加锁处理)

#db.txt{"count": 1}--------------------------------from  multiprocessing import Process,Lockimport json,time,osdef 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()

思考:

购票行为由并发变成了串行,牺牲了运行效率,但保证了数据安全,那为什么不用join将并发改成 串行?答:使用join将并发改成串行,确实可以保证数据的安全,但就变成查票操作也就变成了只能一个一个人去查了,很明显大家查票是并发的去查询而无需数据准确与否,此时join和互斥锁的区别就显而易见了,join是将一个任务 整体串行,而互斥锁的好处就是可以将一个任务的某个代码串行,比如只让task函数中的get任务串行

总结:

#加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,没错,速度是慢了,但牺牲了速度却保证了数据安全。虽然可以用文件共享数据实现进程间通信,但问题是:1.效率低(共享数据基于文件,而文件是硬盘上的数据)2.需要自己加锁处理#因此我们最好找寻一种解决方案能够兼顾:1、效率高(多个进程共享一块内存的数据)2、帮我们处理好锁问题。这就是mutiprocessing模块为我们提供的基于消息的IPC通信机制:队列和管道。1 队列和管道都是将数据存放于内存中2 队列又是基于(管道+锁)实现的,可以让我们从复杂的锁问题中解脱出来,我们应该尽量避免使用共享数据,尽可能使用消息传递和队列,避免处理复杂的同步和锁问题,而且在进程数目增多时,往往可以获得更好的可获展性。

转载于:https://www.cnblogs.com/demiao/p/11530339.html

你可能感兴趣的文章
第三次作业
查看>>
Codeforces 962 /2错误 相间位置排列 堆模拟 X轴距离最小值 前向星点双连通分量求只存在在一个简单环中的边...
查看>>
Matrix快速幂 模板
查看>>
laravel command调用方法命令
查看>>
20162302 - 20162319 结对编程项目-四则运算(第一周)
查看>>
用python2和python3伪装浏览器爬取网页
查看>>
MySQL开启远程连接权限
查看>>
tomcat7.0.27的bio,nio.apr高级运行模式
查看>>
SAP HANA 三大特点
查看>>
C#预处理器命令
查看>>
苹果手表:大方向和谷歌一样,硬件分道扬镳
查看>>
ccf 出现次数最多的数
查看>>
单例模式
查看>>
Competing Consumers Pattern (竞争消费者模式)
查看>>
HDUOJ ------1398
查看>>
cf--------(div1)1A. Theatre Square
查看>>
Android面试收集录15 Android Bitmap压缩策略
查看>>
Tomcat 报错的解决方法:The APR based Apache Tomcat Native library which allows optimal
查看>>
最长公共子串问题(LCS)
查看>>
TortoiseSVN is locked in another working copy
查看>>