python 并发编程 多进程 模拟抢票
抢票是并发执行
多个进程可以访问同一个文件
多个进程共享同一文件,我们可以把文件当数据库,用多个进程模拟多个人执行抢票任务
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并发编程&多进程(二)
前导理论知识见:python并发编程&多进程(一) 一 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_cou ...
- python 并发编程 多进程 互斥锁 目录
python 并发编程 多进程 互斥锁 模拟抢票 互斥锁与join区别
- python并发编程&多进程(一)
本篇理论居多,实际操作见: python并发编程&多进程(二) 一 什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行) ...
- Python并发编程-多进程
Python并发编程-多进程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.多进程相关概念 由于Python的GIL全局解释器锁存在,多线程未必是CPU密集型程序的好的选择. ...
- python 并发编程 多进程 目录
python multiprocessing模块 介绍 python 开启进程两种方法 python 并发编程 查看进程的id pid与父进程id ppid python 并发编程 多进程 Proce ...
- python 并发编程 多进程 队列目录
python 并发编程 多进程 队列 python 并发编程 多进程 生产者消费者模型介绍 python 并发编程 多进程 生产者消费者模型总结 python 并发编程 多进程 JoinableQue ...
- python 并发编程-- 多进程
一 multiprocessing 模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程 ...
- python 并发编程 多进程 互斥锁与join区别
互斥锁与join 互斥锁和join都可以把并发变成串行 以下代码是用join实现串行 from multiprocessing import Process import time import js ...
- python 并发编程 多进程 生产者消费者模型介绍
一 生产者消费者模型介绍 为什么要使用生产者消费者模型 生产者指的是生产数据的任务,消费者指的是处理数据的任务, 生产数据目的,是为了给消费者处理. 在并发编程中,如果生产者处理速度很快,而消费者处理 ...
随机推荐
- C语言中time函数和localtime获取系统时间和日期
可以通过time()函数来获得计算机系统当前的日历时间(Calendar Time),处理日期时间的函数都是以本函数的返回值为基础进行运算. 1. time 函数 返回1970-1-1, 00:00: ...
- 【NOIP2016提高A组模拟10.15】算循环
题目 分析 一步步删掉循环, 首先,原式是\[\sum_{i=1}^n\sum_{j=1}^m\sum_{k=i}^n\sum_{l=j}^m\sum_{p=i}^k\sum_{q=j}^l1\] 删 ...
- 对Canvas的研究
1.标签定义图形,比如图表和其他图像,您必须使用脚本来绘制图形. 什么是 canvas? HTML5 <canvas> 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成. ...
- datatable 和实体互转
public static class ModelConvertHelper<T> where T : class,new() { public static List<T> ...
- Elastic-Job快速入门
1 Elastic-Job快速入门1.1 环境搭建1.1.1.版本要求JDK要求1.7及以上版本Maven要求3.0.4及以上版本zookeeper要求采用3.4.6及以上版本1.1.2.Zookee ...
- Vue(核心思想)
1.Es6语法普及 let和var的区别: var:定义变量时,在全局范围内都有效;所以在变量没有声明之前就能使用,值为undefined, 称为变量提升; let:声明的变量一定要在声明后使用,而且 ...
- Monkeyrunner自动化测试由浅入深(第一节)
(原版)Monkeyrunner自动化测试由浅入深(第一节) 博主原创,请勿转载 第一.相关软件和环境的配置 1.Android sdk下载和配置 2.java jdk下载和配置 第二.Monkeyr ...
- SQL中的schema()函数可替代database()
- esLint——规范你的代码(转)
团队协作时,若是团队的代码风格统一,能够大大减少沟通成本. 什么是 ESLint ? ESLint 是在 ECMAScript/JavaScript 代码中识别和报告模式匹配的工具,它的目标是保证代码 ...
- http三次握手,四次挥手
本文经过借鉴书籍资料.他人博客总结出的知识点,欢迎提问 序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生:给字节编上序号后 ...