进程锁Lock

例1:

10个人去买票,先去查询余票,有票就去购买。代码如下:

# ticket.py
{"ticket": 1}  # 只有一张票

 

import json
import time
from multiprocessing import Process
from multiprocessing import Lock

def show(i):  # 查询票
    with open('ticket') as f:  # 读取文件
        dic = json.load(f)  
    print('余票:%s'%dic['ticket'])  # 余票,所以人都能查到票

def buy_ticket(i):  # 买票,这个代买只有一张票,但是所有人都能买,但是打印发现好几个人买到票了,几个人没买到票。这不符合需求,因为在一个进程买票后,去修改票数时,由于时间太快,没来得及修改,就回到是其他进程买到票。
    with open('ticket') as f:  # 读票数
        dic = json.load(f)
        time.sleep(0.1)
    if dic['ticket'] > 0:  # 判断条件
        dic['ticket'] -= 1  # 票数减1
        print('%s号买到票了'%i)
    else:
        print('%s号没买到票'%i)
        time.sleep(0.1)
    with open('ticket', 'w') as f:  # 将减1后的票数写入到文件
        json.dump(dic, f)


if __name__ == '__main__':
    for i in range(10):  # 生成10个进程
        p = Process(target=show, args=(i,))  # 查询票
        p.start()
    lock = Lock()
    for i in range(10):
        p = Process(target=buy_ticket, args=(i,))  # 买票
        p.start()

解决办法:加锁

好比一个上锁的房间,门口只有一个钥匙,一个线程拿到钥匙进去修改数据没出来前,其他进程只能等着。

import json
import time
from multiprocessing import Process
from multiprocessing import Lock  # 加锁

def show(i):
    with open('ticket') as f:
        dic = json.load(f)
    print('余票:%s'%dic['ticket'])

def buy_ticket(i, lock):  # 接收锁
    lock.acquire()  # 拿钥匙进门
    with open('ticket') as f:
        dic = json.load(f)
        time.sleep(0.1)
    if dic['ticket'] > 0:
        dic['ticket'] -= 1
        print('%s号买到票了'%i)
    else:
        print('%s号没买到票'%i)
        time.sleep(0.1)
    with open('ticket', 'w') as f:
        json.dump(dic, f)
    lock.release()  # 还钥匙


if __name__ == '__main__':
    for i in range(10):
        p = Process(target=show, args=(i,))
        p.start()
    lock = Lock()  # 实例化
    for i in range(10):
        p = Process(target=buy_ticket, args=(i,lock))  # 传入锁
        p.start()

这样会出现有几张票就只有几个人能买票了,数据就安全了。

 

posted @ 2018-10-12 17:12  aaronthon  阅读(807)  评论(0编辑  收藏  举报