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中的异常处理学习笔记
Jan 28 Python
Python中的字符串类型基本知识学习教程
Feb 04 Python
微信 用脚本查看是否被微信好友删除
Oct 28 Python
CentOS 7下安装Python 3.5并与Python2.7兼容并存详解
Jul 07 Python
python判断字符串是否是json格式方法分享
Nov 07 Python
Python企业编码生成系统之系统主要函数设计详解
Jul 26 Python
Python 装饰器@,对函数进行功能扩展操作示例【开闭原则】
Oct 17 Python
PyCharm GUI界面开发和exe文件生成的实现
Mar 04 Python
Python操作Jira库常用方法解析
Apr 10 Python
在tensorflow实现直接读取网络的参数(weight and bias)的值
Jun 24 Python
Python切片列表字符串如何实现切换
Aug 06 Python
MoviePy常用剪辑类及Python视频剪辑自动化
Dec 18 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中将html中的br换行符转换为文本输入中的换行符
2013/03/26 PHP
输入值/表单提交参数过滤有效防止sql注入的方法
2013/12/25 PHP
PHP中使用localhost连接Mysql不成功的解决方法
2014/08/20 PHP
php实现字符串反转输出的方法
2015/03/14 PHP
PHP输出九九乘法表代码实例
2015/03/27 PHP
Laravel 的数据库迁移的方法
2017/07/31 PHP
Laravel程序架构设计思路之使用动作类
2018/06/07 PHP
用JavaScript获取网页中的js、css、Flash等文件
2006/12/20 Javascript
json 实例详细说明教程
2009/10/31 Javascript
ExtJS 学习专题(一) 如何应用ExtJS(附实例)
2010/03/11 Javascript
给html超链接设置事件不使用href来完成跳
2014/04/20 Javascript
javascript在当前窗口关闭前检测窗口是否关闭
2014/09/29 Javascript
js获取指定字符前/后的字符串简单实例
2016/10/27 Javascript
基于Vuejs框架实现翻页组件
2020/06/29 Javascript
玩转NODE.JS(四)-搭建简单的聊天室的代码
2016/11/11 Javascript
微信小程序动态显示项目倒计时效果
2017/06/13 Javascript
NodeJS实现图片上传代码(Express)
2017/06/30 NodeJs
vue中进入详情页记住滚动位置的方法(keep-alive)
2018/09/21 Javascript
为nuxt项目写一个面包屑cli工具实现自动生成页面与面包屑配置
2019/09/29 Javascript
JavaScript 变量,数据类型基础实例详解【变量、字符串、数组、对象等】
2020/01/04 Javascript
python使用fileinput模块实现逐行读取文件的方法
2015/04/29 Python
Python2.X/Python3.X中urllib库区别讲解
2017/12/19 Python
Django Web开发中django-debug-toolbar的配置以及使用
2018/05/06 Python
Python 200行代码实现一个滑动验证码过程详解
2019/07/11 Python
Python pandas RFM模型应用实例详解
2019/11/20 Python
pandas中read_csv的缺失值处理方式
2019/12/19 Python
Python实现封装打包自己写的代码,被python import
2020/07/12 Python
有关HTML5页面在iPhoneX适配问题
2017/11/13 HTML / CSS
编写一个类体现构造,公有,私有方法,静态,私有变量
2013/08/10 面试题
个人培训自我鉴定
2014/03/28 职场文书
关于感恩的演讲稿800字
2014/08/26 职场文书
大学生第一学年自我鉴定2015
2014/09/28 职场文书
作风转变年心得体会
2014/10/22 职场文书
六一亲子活动感想
2015/08/07 职场文书
html form表单基础入门案例讲解
2021/07/15 HTML / CSS
详解Alibaba Java诊断工具Arthas查看Dubbo动态代理类
2022/04/08 Java/Android