抢票是并发执行

多个进程可以访问同一个文件

多个进程共享同一文件,我们可以把文件当数据库,用多个进程模拟多个人执行抢票任务

db.txt

{"count": 1}

并发运行,效率高,但竞争写同一文件,数据写入错乱,只有一张票,都卖成功给了10个人

#文件db.txt的内容为:{"count":1}
#注意一定要用双引号,不然json无法识别 from multiprocessing import Process
import time
import json class Foo(object): def search(self, name): with open("db.txt", "r") as f_read:
dic = json.load(f_read) time.sleep(1) # 模拟读数据的网络延迟
print("<%s>用户 查看剩余票数为 [%s]" % (name, dic["count"])) def get(self, name): with open("db.txt", "r") as f_read:
dic = json.load(f_read) if dic["count"] > 0:
dic["count"] -= 1
time.sleep(1) # 模拟写数据的网络延迟 with open("db.txt", "w") as f_write:
json.dump(dic, f_write) print("<%s> 购票成功" % name)
print("剩余票数为 [%s]" % dic["count"]) else:
print("没票了,抢光了") def task(self, name):
self.search(name)
self.get(name) if __name__ == "__main__": obj = Foo()
for i in range(1,11): # 模拟并发10个客户端抢票
p = Process(target=obj.task, args=("路人%s" % i,))
p.start()

总结:程序出现数据写入错乱

大家都查到票为1,都购票成功

<路人1>用户 查看剩余票数为 [1]
<路人2>用户 查看剩余票数为 [1]
<路人3>用户 查看剩余票数为 [1]
<路人4>用户 查看剩余票数为 [1]
<路人5>用户 查看剩余票数为 [1]
<路人6>用户 查看剩余票数为 [1]
<路人7>用户 查看剩余票数为 [1]
<路人8>用户 查看剩余票数为 [1]
<路人9>用户 查看剩余票数为 [1]
<路人10>用户 查看剩余票数为 [1]
<路人1> 购票成功
剩余票数为 [0]
<路人2> 购票成功
剩余票数为 [0]
<路人3> 购票成功
剩余票数为 [0]
<路人4> 购票成功
剩余票数为 [0]
<路人5> 购票成功
剩余票数为 [0]
<路人6> 购票成功
剩余票数为 [0]
<路人7> 购票成功
剩余票数为 [0]
<路人8> 购票成功
剩余票数为 [0]
<路人9> 购票成功
剩余票数为 [0]
<路人10> 购票成功
剩余票数为 [0] 总结程序出现数据写入错乱

加锁处理:购票行为由并发变成了串行,牺牲了运行效率,但保证了数据安全

购票功能不应该并发执行,查票应该是并发执行的

查票准不准确不重要,有可能这张票就被别人买走

一个人写完以后,让另外一个人基于上一个人写的结果,再做购票操作

#把文件db.txt的内容重置为:{"count":1}
from multiprocessing import Process
from multiprocessing import Lock
import time
import json class Foo(object): def search(self, name): with open("db.txt", "r") as f_read:
dic = json.load(f_read) time.sleep(1) # 模拟读数据的网络延迟
print("<%s>用户 查看剩余票数为 [%s]" % (name, dic["count"])) def get(self, name): with open("db.txt", "r") as f_read:
dic = json.load(f_read) if dic["count"] > 0:
dic["count"] -= 1
time.sleep(1) # 模拟写数据的网络延迟 with open("db.txt", "w") as f_write:
json.dump(dic, f_write) print("<%s> 购票成功" % name)
print("剩余票数为 [%s]" % dic["count"]) else:
print("没票了,抢光了") def task(self, name, mutex):
self.search(name) mutex.acquire()
self.get(name)
mutex.release() if __name__ == "__main__": mutex = Lock()
obj = Foo()
for i in range(1,11): # 模拟并发10个客户端抢票
p = Process(target=obj.task, args=("路人%s" % i, mutex))
p.start()

执行结果

<路人2>用户 查看剩余票数为 [1]
<路人3>用户 查看剩余票数为 [1]
<路人1>用户 查看剩余票数为 [1]
<路人4>用户 查看剩余票数为 [1]
<路人5>用户 查看剩余票数为 [1]
<路人7>用户 查看剩余票数为 [1]
<路人6>用户 查看剩余票数为 [1]
<路人8>用户 查看剩余票数为 [1]
<路人9>用户 查看剩余票数为 [1]
<路人10>用户 查看剩余票数为 [1]
<路人2> 购票成功
剩余票数为 [0]
没票了,抢光了
没票了,抢光了
没票了,抢光了
没票了,抢光了
没票了,抢光了
没票了,抢光了
没票了,抢光了
没票了,抢光了
没票了,抢光了

with lock

相当于lock.acquire(),执行完自代码块自动执行lock.release()
from multiprocessing import Process
from multiprocessing import Lock
import time
import json class Foo(object): def search(self, name): with open("db.txt", "r") as f_read:
dic = json.load(f_read) time.sleep(1) # 模拟读数据的网络延迟
print("<%s>用户 查看剩余票数为 [%s]" % (name, dic["count"])) def get(self, name): with open("db.txt", "r") as f_read:
dic = json.load(f_read) if dic["count"] > 0:
dic["count"] -= 1
time.sleep(1) # 模拟写数据的网络延迟 with open("db.txt", "w") as f_write:
json.dump(dic, f_write) print("<%s> 购票成功" % name)
print("剩余票数为 [%s]" % dic["count"]) else:
print("没票了,抢光了") def task(self, name, mutex):
self.search(name) with mutex: # 相当于lock.acquire(),执行完自代码块自动执行lock.release()
self.get(name) if __name__ == "__main__": mutex = Lock()
obj = Foo()
for i in range(1,11): # 模拟并发10个客户端抢票
p = Process(target=obj.task, args=("路人%s" % i, mutex))
p.start()
												

python 并发编程 多进程 模拟抢票的更多相关文章

  1. python并发编程&多进程(二)

    前导理论知识见:python并发编程&多进程(一) 一 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_cou ...

  2. python 并发编程 多进程 互斥锁 目录

    python 并发编程 多进程 互斥锁 模拟抢票 互斥锁与join区别

  3. python并发编程&多进程(一)

    本篇理论居多,实际操作见:  python并发编程&多进程(二) 一 什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行) ...

  4. Python并发编程-多进程

    Python并发编程-多进程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.多进程相关概念 由于Python的GIL全局解释器锁存在,多线程未必是CPU密集型程序的好的选择. ...

  5. python 并发编程 多进程 目录

    python multiprocessing模块 介绍 python 开启进程两种方法 python 并发编程 查看进程的id pid与父进程id ppid python 并发编程 多进程 Proce ...

  6. python 并发编程 多进程 队列目录

    python 并发编程 多进程 队列 python 并发编程 多进程 生产者消费者模型介绍 python 并发编程 多进程 生产者消费者模型总结 python 并发编程 多进程 JoinableQue ...

  7. python 并发编程-- 多进程

    一 multiprocessing 模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程 ...

  8. python 并发编程 多进程 互斥锁与join区别

    互斥锁与join 互斥锁和join都可以把并发变成串行 以下代码是用join实现串行 from multiprocessing import Process import time import js ...

  9. python 并发编程 多进程 生产者消费者模型介绍

    一 生产者消费者模型介绍 为什么要使用生产者消费者模型 生产者指的是生产数据的任务,消费者指的是处理数据的任务, 生产数据目的,是为了给消费者处理. 在并发编程中,如果生产者处理速度很快,而消费者处理 ...

随机推荐

  1. java初学者的Springmvc04笔记

    Springmvc04 Springmvc的全局异常处理 springmvc与spring的整合 myBatis 1.Springmvc的全局异常处理 作用:一次配置,对于controller层的所有 ...

  2. 织梦dedecms自定义表单导出到excel教程

    不写死任何字段,不写死任何东西,修改2个文件,让织梦自定义表单自由导出到Excel表格里. 添加教程 1.\dede\templets\diy_main.htm 找到 前台预览</a> 在 ...

  3. IDC装机检查思路

    交换机网口 网线 配线架 服务器网口灯 系统网卡驱动

  4. linux 下u盘只读

    使用linux不管是centos还是ubuntu的小伙伴都难免遇到插入U盘的时候,不能对U盘进行操作.提示权限不足或者是只读文件系统. 现在教你三行命令教你解决U盘只读文件系统的问题. 1.插入U盘并 ...

  5. Centos7安装Redis3.X

    本文只是简单搭建Redis,为了整合ELK用,后面会详细写. Redis:REmote DIctionary Server(远程字典服务器) 是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高 ...

  6. vue 使用 axios 时 post 请求方法传参无法发送至后台

    axios 时 post 请求方法传参无法发送至后台报错如下 Response to preflight request doesn't pass access control check: No ' ...

  7. AttributeError: module 'datetime' has no attribute 'now'

    在用时间转化时,一直报AttributeError: module 'datetime' has no attribute 'now', 我用的 import datetime   datetime ...

  8. (58)PHP开发

    LAMP 0.使用include和require命令来包含外部PHP文件. 使用include_once命令,但是include和include_once命令相比的不足就是这两个命令并不关心请求的文件 ...

  9. Python实现用户注册到文件

    import getpass #引入getpass模块,主要用来输入密码关闭回显 f=open('d:/user','a+') #定义文件对象并以追加方式打开,不存在就创建 f.seek(0) #文件 ...

  10. linux服务器在线测速

    cd /tmpwget https://raw.github.com/sivel/speedtest-cli/master/speedtest.py或者wget https://raw.githubu ...