银行存取钱
银行存取钱是同时对一个数据操作,容易造成数据混乱,解决方法是加锁
from multiprocessing import Process from time import sleep def get_money(num): # 取钱 num -= 1 print('子进程:', num) if __name__ == '__main__': money_num = 100 p = Process(target=get_money, args=(money_num,)) p.start() p.join() # 等子进程结束 print(money_num)
结果:
子进程: 99 100
数据不共享原因导致的
共享内存
from multiprocessing import Process, Value from time import sleep def get_money(num): # 取钱 num.value -= 1 print('子进程:', num.value) if __name__ == '__main__': money_num = Value('i', 100) p = Process(target=get_money, args=(money_num,)) p.start() p.join() print(money_num.value)
结果:
子进程: 99 99
要共享内存有多个方法,这里用Value,首先要导入,money_num=Value('i',100)这句话的Value接收两个参数,第一个是数据类型,第二个是这个类型的值,取值的时候要用x.value
银行取钱问题
from multiprocessing import Process, Value from time import sleep def get_money(num): # 取钱 for i in range(100): num.value -= 1 sleep(0.01) def put_money(num): # 存取 for i in range(100): num.value += 1 sleep(0.01) if __name__ == '__main__': money_num = Value('i', 100) p = Process(target=get_money, args=(money_num,)) p.start() # 取钱 p1 = Process(target=put_money, args=(money_num,)) p1.start() # 存取 p1.join() p.join() print(money_num.value)
多执行几次,有时候是100,有时候小于100,有时候大于100
锁 Lock
from multiprocessing import Process, Lock l = Lock() # 实例化 l.acquire() # 加锁。拿走钥匙,锁门,不让其他人进屋 l.release() # 释放锁。还钥匙,开门,允许其他人进屋
银行存取钱加锁
from multiprocessing import Process, Value, Lock from time import sleep def get_money(num, l): # 取钱 l.acquire() for i in range(100): num.value -= 1 sleep(0.01) l.release() def put_money(num, l): # 存取 for i in range(100): l.acquire() # 建议小范围的加锁 num.value += 1 l.release() sleep(0.01) if __name__ == '__main__': l = Lock() # 实例化锁 money_num = Value('i', 100) p = Process(target=get_money, args=(money_num, l)) p.start() # 取钱 p1 = Process(target=put_money, args=(money_num, l)) p1.start() # 存取 p1.join() p.join() print(money_num.value)
不管操作多少次都是100
遇见l.acquire()给数据加个锁,别的进程就不能操作这个数据了,直到l.release()之后其他的进程才可以操作锁,建议小范围内加锁
模拟 12306 强票
from multiprocessing import Process, Lock import time def check(i): with open('余票') as f: con = f.read() print('第%s个人查到余票还剩%s张' % (i, con)) def buy_ticket(i, l): l.acquire() # 拿钥匙,锁门 with open('余票') as f: con = int(f.read()) time.sleep(0.1) if con > 0: print('\033[31m 第%s个人买到票了\033[0m' % i) con -= 1 else: print('\033[32m 第%s个人没有买到票\033[0m' % i) time.sleep(0.1) # 是指 买完票后,把余票数量重写写入数据库的时间延迟 with open('余票', 'w') as f: f.write(str(con)) l.release() # 还钥匙,开门 if __name__ == '__main__': l = Lock() for i in range(10): p_ch = Process(target=check, args=(i + 1,)) p_ch.start() for i in range(10): p_buy = Process(target=buy_ticket, args=(i + 1, l)) p_buy.start()
新建一个 “余票” 的文件,写个12
执行结果
第1个人查到余票还剩12张 第2个人查到余票还剩12张 第3个人查到余票还剩12张 第4个人查到余票还剩12张 第5个人查到余票还剩12张 第6个人查到余票还剩12张 第7个人查到余票还剩12张 第8个人查到余票还剩12张 第9个人查到余票还剩12张 第10个人查到余票还剩12张 第1个人买到票了 第2个人买到票了 第3个人买到票了 第4个人买到票了 第5个人买到票了 第6个人买到票了 第7个人买到票了 第8个人买到票了 第9个人买到票了 第10个人买到票了