互斥锁

什么时候用锁?

当多进程同时读写同一份数据,数据可能被破坏

例如:第一个进程写了一个中文字符的一个字节,cpu就切到另外一个进程,另一个今晨也写了一个中文字符的一个字节。

最后文件解码失败

问题之所以出现是因为并发无法控制顺序。

目前可以使用join 来将所有进程的并发改成串行。

锁与join 的区别?

多进程并发的访问了同一资源,将导致资源竞争( 同时读取不会产生问题 同时修改才会产生问题)

第一方案 加上join 单数这样就导致不公平,相当强行规定执行的顺序

第二方法 加锁 谁在cpu分配到资源,谁先处理

相同点:都变成串行

不同点:

1.join顺序固定,锁顺序不固定!

2.join使整个进程的任务全部串行,而锁可以指定哪些代码要串行。

锁是什么

锁的本质上就是一个bool类型的标识符,多进程在执行任务之前会先判断标识符。

互斥锁 两个进程相互排斥。

注意点: 想要锁住资源必须保证,大家拿到是一把锁

怎么使用锁

在需要加锁的地方 lock.acquire() 标识锁定

在代码执行完后,一定要lock.release() 表示释放锁定。

lock.acquire()

放在需要竞争资源的代码(同时写入数据)

lock.release()

基础使用

from multiprocessing import Process,Lock

metux = Lock()#生成锁

def task1(lock):
    lock.acquire()#上锁
    for i in range(20):
        print("========================")
    lock.release()#释放锁

def task2(lock):
    lock.acquire()
    for i in range(20):
        print("**************************")
    lock.release()

def task3(lock):
    lock.acquire()
    for i in range(20):
        print("???????????????????????????")
    lock.release()

if __name__ == '__main__':
    p1 = Process(target=task1,args=(metux,))#使用同一把锁才能产生组织其他线程争抢资源的
    p2 = Process(target=task2, args=(metux,))
    p3 = Process(target=task3, args=(metux,))

    p1.start()
    p2.start()
    p3.start()

抢票

import json
import time
import random
from multiprocessing import Process,Lock

#查看票务的进程
def check_ticket(name):
    time.sleep(random.randint(1,3))
    with open(r'ticket.json',"r",encoding="utf-8") as f:
        dic = json.load(f)
    print("%s 查看 当前票数为%s张"%(name,dic["count"]))


def buy_ticket(name):
    with open(r'ticket.json',"r",encoding="utf-8") as f:
        dic = json.load(f)
    if dic["count"]>0:
        dic["count"] -= 1
        time.sleep(random.randint(1,3))
        with open(r'ticket.json',"w",encoding="utf-8") as f2:
            dic = json.dump(dic,f2)
            print("%s购票成功 "%(name))


def run(name,lock):
    check_ticket(name)
    lock.acquire()
    buy_ticket(name)
    lock.release()

if __name__ == '__main__':
    metux = Lock()
    for i in range(1,10):
        name = "顾客%s"%i
        p = Process(target=run,args=(name,metux))
        p.start()

 

 

 

posted @ 2018-11-09 18:54  msjaxuexi  阅读(157)  评论(0编辑  收藏  举报