python并发编程多进程 模拟抢票实现过程


Posted in Python onAugust 20, 2019

 抢票是并发执行

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

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

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 相关文章推荐
python实现问号表达式(?)的方法
Nov 27 Python
小结Python用fork来创建子进程注意事项
Jul 03 Python
python自动化测试之连接几组测试包实例
Sep 28 Python
python实现俄罗斯方块
Jun 26 Python
Python 比较文本相似性的方法(difflib,Levenshtein)
Oct 15 Python
Python面向对象之类的定义与继承用法示例
Jan 14 Python
对django2.0 关联表的必填on_delete参数的含义解析
Aug 09 Python
Python依赖包整体迁移方法详解
Aug 15 Python
解决echarts中饼图标签重叠的问题
May 16 Python
基于python SMTP实现自动发送邮件教程解析
Jun 02 Python
基于python实现简单网页服务器代码实例
Sep 14 Python
如何用Python提取10000份log中的产品信息
Jan 14 Python
python3的数据类型及数据类型转换实例详解
Aug 20 #Python
Python列表的切片实例讲解
Aug 20 #Python
python并发编程多进程 互斥锁原理解析
Aug 20 #Python
django 配置阿里云OSS存储media文件的例子
Aug 20 #Python
python数据类型之间怎么转换技巧分享
Aug 20 #Python
python并发编程多进程之守护进程原理解析
Aug 20 #Python
python控制台实现tab补全和清屏的例子
Aug 20 #Python
You might like
如何用php获取文件名后缀
2013/06/09 PHP
CI框架出现mysql数据库连接资源无法释放的解决方法
2016/05/17 PHP
如何离线执行php任务
2017/02/21 PHP
创建无限极分类树型结构的简单方法
2017/06/20 PHP
ThinkPHP框架下微信支付功能总结踩坑笔记
2019/04/10 PHP
详解PHP PDO简单教程
2019/05/28 PHP
JavaScript 数组循环引起的思考
2010/01/01 Javascript
jquery动画2.元素坐标动画效果(创建一个图片走廊)
2012/08/24 Javascript
基于jQuery实现文本框缩放以及上下移动功能
2014/11/24 Javascript
为何JS操作的href都是javascript:void(0);呢
2015/11/12 Javascript
js实现消息滚动效果
2017/01/18 Javascript
servlet+jquery实现文件上传进度条示例代码
2017/01/25 Javascript
ES6数组的扩展详解
2017/04/25 Javascript
浅谈React碰到v-if
2018/11/04 Javascript
vue基础之事件v-onclick=&quot;函数&quot;用法示例
2019/03/11 Javascript
javascript 代码是如何被压缩的示例代码
2020/05/06 Javascript
JavaScript设计模式---单例模式详解【四种基本形式】
2020/05/16 Javascript
微信小程序 wx:for 与 wx:for-items 与 wx:key的正确用法
2020/05/19 Javascript
在Vue中使用Echarts可视化库的完整步骤记录
2020/11/18 Vue.js
[04:03]DOTA2肉山黑名单梦之声 风暴之灵中文配音鉴赏
2013/07/03 DOTA
python小技巧之批量抓取美女图片
2014/06/06 Python
python中使用序列的方法
2015/08/03 Python
python select.select模块通信全过程解析
2017/09/20 Python
python中将正则过滤的内容输出写入到文件中的实例
2018/10/21 Python
python、Matlab求定积分的实现
2019/11/20 Python
解决ROC曲线画出来只有一个点的问题
2020/02/28 Python
阿迪达斯比利时官方商城:adidas比利时
2016/10/10 全球购物
加拿大的标志性百货公司:Hudson’s Bay(哈得逊湾)
2019/09/03 全球购物
ManoMano英国:欧洲第一家专注于DIY和园艺市场的电商平台
2020/03/12 全球购物
Servlet的生命周期
2013/08/25 面试题
入党综合考察材料
2014/06/02 职场文书
2015年世界环境日活动总结
2015/02/11 职场文书
自主招生自荐信范文
2015/03/04 职场文书
Python 中random 库的详细使用
2021/06/03 Python
用PYTHON去计算88键钢琴的琴键频率和音高
2022/04/10 Python
Python函数对象与闭包函数
2022/04/13 Python