python学习笔记 day36 锁

1. 锁-并发编程中用来确保数据安全

应用----抢票:

方法一: 不使用锁,直接开多个进程实现抢票:(by myself)

from multiprocessing import Process,Lock
import json

def search_ticket(i):  # i 表示第i个进程执行的任务
    with open("ticket") as f:
        ticket_num=json.load(f)["count"]
        return ticket_num
def get_ticket(i):  # i表示第i个进程执行的任务
    ticket_num=search_ticket(i)
    if ticket_num:
        with open("ticket","w",encoding="utf-8") as f:
            json.dump({"count":ticket_num-1},f)  # 抢到一张票后需要把余票进行减一操作,然后使用json.dump(content,f)写进文件中
        print(i,"抢到票了")
    else:
        print(i,"没有抢到票")

if __name__=="__main__":
    for i in range(20):
        p=Process(target=get_ticket,args=(i,))
        p.start()

运行结果:

上面的方法虽然也完成了抢票的功能(这里运行并没有出错,但是总感觉是有问题的,因为同时开多个进程,有可能在同一时间多个进程同时操作同一个文件,读写混乱,最好不要这样写)

方法二: 使用并发编程(开多个进程来实现)和 锁 来实现抢票(就是同一时间只有一个进程可以操作数据,不是所以进程都操作同一个文件,保证了数据的安全性)--(by Eva)

from multiprocessing import Process,Lock
import json
def search_ticket(i):  # 查看余票,i表示第i个进程
    with open("ticket") as f:
        ticket_num=json.load(f)["count"]  # 使用json的load把字符串形式的字典{"count":4} 转化为字典
        print(i,"还有余票%s"%ticket_num)

def get_ticket(i): # i 表示第i个进程
    with open("ticket") as f:
        ticket_num=json.load(f)["count"]
    if ticket_num:  # 如果还有余票
        with open("ticket","w",encoding="utf-8") as f:  # 当还有余票时,才进行购买,然后往文件中更新票数
            json.dump({"count":ticket_num-1},f)  # 购买一张票,更新余票(把字典使用json.dump(content,f)写进文件f中)
            print(i,"抢到票了")
    else:
        print(i,"未能抢到票")
def task(i,lock):
    search_ticket(i)  # 所有进程都可以同时查看余票,但是购买票在同一时间只有一个进程来操作
    lock.acquire()    # 需要锁,拿钥匙 该时间只有一个进程会执行下面的get_ticket()
    get_ticket(i)     # 拿到钥匙的进程执行购买操作
    lock.release()    # 购买完之后,释放锁,归还钥匙

if __name__=="__main__":
    lock=Lock()  # 创建一个锁对象
    for i in range(20):
        p=Process(target=task,args=(i,lock))
        p.start()

运行结果:

 

猜你喜欢

转载自www.cnblogs.com/xuanxuanlove/p/9771615.html