• 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个人买到票了
  • 相关阅读:
    cs231n.stanford.edu
    cs229.stanford.edu
    Boost circular_buffer example
    OI中一些常见实用的套路【更新中】
    用Java读取xml文件内容
    在控制台中操作MYSQL数据库步骤以及一些小问题
    java 实现对指定目录的文件进行下载
    将java项目发布到本地的linux虚拟机上
    mybatis 控制台打印出来的sql 执行结果为空 但是将sql放到mysql执行有数据
    spring mvc 拦截器
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/13775296.html
Copyright © 2020-2023  润新知