python-- 锁Lock

银行存取钱

银行存取钱是同时对一个数据操作,容易造成数据混乱,解决方法是加锁

复制代码
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个人买到票了
复制代码

 

posted @   邹邹很busy。  阅读(97)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
历史上的今天:
2019-07-13 python--装饰器
点击右上角即可分享
微信分享提示

目录导航