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 @ 2021-07-13 22:37  邹邹很busy。  阅读(86)  评论(0编辑  收藏  举报