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文件操作整理汇总
Oct 21 Python
python正则表达式中的括号匹配问题
Dec 14 Python
Python3实现发送QQ邮件功能(html)
Dec 15 Python
Python多层装饰器用法实例分析
Feb 09 Python
Python查找两个有序列表中位数的方法【基于归并算法】
Apr 20 Python
virtualenv 指定 python 解释器的版本方法
Oct 25 Python
对python requests发送json格式数据的实例详解
Dec 19 Python
Python实现的文轩网爬虫完整示例
May 16 Python
Django实现WebSSH操作物理机或虚拟机的方法
Nov 06 Python
解决pyCharm中 module 调用失败的问题
Feb 12 Python
Pytorch 使用 nii数据做输入数据的操作
May 26 Python
python某漫画app逆向
Mar 31 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 的超链接
2009/06/02 PHP
三个类概括PHP的五种设计模式
2012/09/05 PHP
php中unlink()、mkdir()、rmdir()等方法的使用介绍
2012/12/21 PHP
基于flush()不能按顺序输出时的解决办法
2013/06/29 PHP
PHP设置Cookie的HTTPONLY属性方法
2017/02/09 PHP
PHP中十六进制颜色与RGB颜色值互转的方法
2019/03/18 PHP
(仅IE下有效)关于checkbox 三态
2007/05/12 Javascript
Javascript 键盘keyCode键码值表
2009/12/24 Javascript
轻轻松松学JS调试(不下载任何工具)
2010/04/14 Javascript
Easyui笔记2:实现datagrid多行删除的示例代码
2017/01/14 Javascript
纯jQuery实现前端分页功能
2017/03/23 jQuery
微信小程序实现手指触摸画板
2018/07/09 Javascript
Vue递归实现树形菜单方法实例
2018/11/06 Javascript
自定义Vue组件打包、发布到npm及使用教程
2019/05/22 Javascript
解决在Vue中使用axios用form表单出现的问题
2019/10/30 Javascript
把大数据数字口语化(python与js)两种实现
2013/02/21 Python
Python中文分词工具之结巴分词用法实例总结【经典案例】
2017/04/15 Python
Python不使用int()函数把字符串转换为数字的方法
2018/07/09 Python
15行Python代码实现网易云热门歌单实例教程
2019/03/10 Python
python字典嵌套字典的情况下找到某个key的value详解
2019/07/10 Python
Python 类的魔法属性用法实例分析
2019/11/21 Python
flask框架自定义url转换器操作详解
2020/01/25 Python
完美解决Pycharm中matplotlib画图中文乱码问题
2021/01/11 Python
美国女孩洋娃娃店:American Girl
2017/10/24 全球购物
Notino瑞典:购买香水和美容产品
2019/07/26 全球购物
阿里巴巴美国:Alibaba美国
2019/11/24 全球购物
Can a struct inherit from another class? (结构体能继承类吗)
2014/07/22 面试题
学期自我鉴定范文
2013/10/01 职场文书
学校岗位设置方案
2014/01/16 职场文书
爱国卫生月实施方案
2014/02/21 职场文书
升职演讲稿范文
2014/05/23 职场文书
2014年加油站站长工作总结
2014/12/23 职场文书
小学生红领巾广播稿
2015/08/19 职场文书
如何用python清洗文件中的数据
2021/06/18 Python
使用ORM新增数据在Mysql中的操作步骤
2021/07/26 MySQL
Nginx设置HTTPS的方法步骤 443证书配置方法
2022/03/21 Servers