zoukankan      html  css  js  c++  java
  • 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('33[31m 第%s个人买到票了33[0m' % i)
            con -= 1
        else:
            print('33[32m 第%s个人没有买到票33[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个人买到票了
  • 相关阅读:
    分分钟提升命令行模式下密码输入逼格
    MySQL server has gone away 的两个最常见的可能性
    第一次遇到刷新缓冲区延时
    Mac上安装mysqlclient的报错
    python3 --- locale命名空间让程序更加安全了
    doctest --- 一个改善python代码质量的工具
    MySQL优化器 --- index_merge
    机智的MySQL优化器 --- is null
    Centos-7.x 下子网掩码的配置
    JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(三):两个Viewmodel搞定增删改查
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/13775296.html
Copyright © 2011-2022 走看看