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多线程爬虫简单示例
Mar 04 Python
Python实现一个转存纯真IP数据库的脚本分享
May 21 Python
Python实现的堆排序算法示例
Apr 29 Python
python无限生成不重复(字母,数字,字符)组合的方法
Dec 04 Python
Python实现查找最小的k个数示例【两种解法】
Jan 08 Python
使用Python的OpenCV模块识别滑动验证码的缺口(推荐)
May 10 Python
了解不常见但是实用的Python技巧
May 23 Python
Python检查图片是否损坏及图片类型是否正确过程详解
Sep 30 Python
pygame实现打字游戏
Feb 19 Python
Python3爬虫发送请求的知识点实例
Jul 30 Python
详解Python流程控制语句
Oct 28 Python
Python中X[:,0]和X[:,1]的用法
May 10 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
第十二节--类的自动加载
2006/11/16 PHP
php设置session值和cookies的学习示例
2014/03/21 PHP
PHP获取网页所有连接的方法(附demo源码下载)
2016/03/30 PHP
Laravel 关联模型-关联新增和关联更新的方法
2019/10/10 PHP
javascript支持firefox,ie7页面布局拖拽效果代码
2007/12/20 Javascript
关于B/S判断浏览器断开的问题讨论
2008/10/29 Javascript
Jquery Validate 正则表达式实用验证代码大全
2013/08/23 Javascript
前台js调用后台方法示例
2013/12/02 Javascript
js解决select下拉选不中问题
2014/10/14 Javascript
JS实现为表格动态添加标题的方法
2015/03/31 Javascript
jQuery移动页面开发中的触摸事件与虚拟鼠标事件简介
2015/12/03 Javascript
jQuery+canvas实现简单的球体斜抛及颜色动态变换效果
2016/01/28 Javascript
AngularJS中处理多个promise的方式
2016/02/02 Javascript
基于javascript实现动态时钟效果
2020/08/18 Javascript
Jquery实现上下移动和排序代码
2016/10/17 Javascript
详解JS几种变量交换方式以及性能分析对比
2016/11/25 Javascript
快速实现jQuery多级菜单效果
2017/02/01 Javascript
js中的数组对象排序分析
2018/12/11 Javascript
微信小程序常用赋值方法小结
2019/04/30 Javascript
ssm+vue前后端分离框架整合实现(附源码)
2020/07/08 Javascript
原生JS实现音乐播放器的示例代码
2021/02/25 Javascript
[50:04]DOTA2上海特级锦标赛D组小组赛#2 Liquid VS VP第二局
2016/02/28 DOTA
[27:08]完美世界DOTA2联赛PWL S2 SZ vs Rebirth 第二场 11.21
2020/11/23 DOTA
python获取一组数据里最大值max函数用法实例
2015/05/26 Python
python导入模块交叉引用的方法
2019/01/19 Python
python读写csv文件并增加行列的实例代码
2019/08/01 Python
Flask模板引擎Jinja2使用实例
2020/04/23 Python
如何使用Pytorch搭建模型
2020/10/26 Python
Pycharm安装第三方库失败解决方案
2020/11/17 Python
职业规划书如何设计?
2014/01/09 职场文书
请假条格式范文
2014/04/10 职场文书
缅怀先烈演讲稿
2014/09/03 职场文书
2015年法院工作总结范文
2015/04/28 职场文书
干货!开幕词的写作方法
2019/04/02 职场文书
pycharm安装深度学习pytorch的d2l包失败问题解决
2022/03/25 Python
Flink 侧流输出源码示例解析
2022/09/23 Servers