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基础入门详解(文件输入/输出 内建类型 字典操作使用方法)
Dec 08 Python
Django中几种重定向方法
Apr 28 Python
Python常用的文件及文件路径、目录操作方法汇总介绍
May 21 Python
Python实现的快速排序算法详解
Aug 01 Python
利用aardio给python编写图形界面
Aug 21 Python
NumPy 如何生成多维数组的方法
Feb 05 Python
对python修改xml文件的节点值方法详解
Dec 24 Python
Python如何使用k-means方法将列表中相似的句子归类
Aug 08 Python
Python3离线安装Requests模块问题
Oct 13 Python
python通过文本在一个图中画多条线的实例
Feb 21 Python
Python过滤掉numpy.array中非nan数据实例
Jun 08 Python
Python爬虫爬取微博热搜保存为 Markdown 文件的源码
Feb 22 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函数
2006/12/06 PHP
PHP常用开发函数解析之数组篇[未完结]
2012/07/30 PHP
深入PHP empty(),isset(),is_null()的实例测试详解
2013/06/06 PHP
php连接oracle数据库及查询数据的方法
2014/12/29 PHP
PHP提取字符串中的手机号正则表达式怎么写
2017/07/17 PHP
JS小功能(onmouseover实现选择月份)实例代码
2013/11/28 Javascript
利用javascript判断文件是否存在
2013/12/31 Javascript
JS往数组中添加项性能分析
2015/02/25 Javascript
JS实现带提示的星级评分效果完整实例
2015/10/30 Javascript
webpack+vue.js实现组件化详解
2016/10/12 Javascript
详解Jquery的事件操作和文档操作
2016/12/19 Javascript
Angularjs中ng-repeat的简单实例
2017/08/25 Javascript
深入理解requireJS-实现一个简单的模块加载器
2018/01/15 Javascript
angular6 利用 ngContentOutlet 实现组件位置交换(重排)
2018/11/02 Javascript
js replace替换字符串同时替换多个方法
2018/11/27 Javascript
vue 2.5.1 源码学习 之Vue.extend 和 data的合并策略
2019/06/04 Javascript
小程序双头slider选择器的实现示例
2020/03/31 Javascript
Python3基础之函数用法
2014/08/13 Python
Python统计文件中去重后uuid个数的方法
2015/07/30 Python
微信跳一跳python辅助脚本(总结)
2018/01/11 Python
python通过配置文件共享全局变量的实例
2019/01/11 Python
详解用Python练习画个美队盾牌
2019/03/23 Python
使用WingPro 7 设置Python路径的方法
2019/07/24 Python
python中web框架的自定义创建
2019/09/08 Python
TensorFlow tf.nn.max_pool实现池化操作方式
2020/01/04 Python
django之从html页面表单获取输入的数据实例
2020/03/16 Python
python实现梯度下降算法的实例详解
2020/08/17 Python
Python 获取异常(Exception)信息的几种方法
2020/12/29 Python
css3绘制百度的小度熊
2018/10/29 HTML / CSS
初中英语教学反思
2014/01/25 职场文书
酒店保安领班职务说明书
2014/03/04 职场文书
资产移交协议书
2016/03/24 职场文书
JS + HTML 罗盘式时钟的实现
2021/05/21 Javascript
pytorch 实现多个Dataloader同时训练
2021/05/29 Python
Python 数据可视化之Seaborn详解
2021/11/02 Python
Python实现科学占卜 让视频自动打码
2022/04/09 Python