(python)互斥锁

进程之间的数据不共享,但可共享同一资源,所以访问同一文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争的结果就会产生错乱。

看下面并发打印三个人的信息:

from  multiprocessing import Process
import random,time

def task1():
    time.sleep(random.randint(1,3))
    print('task1:姓名,xxx')
    time.sleep(random.randint(1, 3))
    print('task1:年龄,34')
    time.sleep(random.randint(1, 3))
    print('task1:性别:男')

def task2():
    time.sleep(random.randint(1,3))
    print('task2:姓名,十三在')
    time.sleep(random.randint(1, 3))
    print('task2:年龄,34')
    time.sleep(random.randint(1, 3))
    print('task2:性别:男')

def task3():
    time.sleep(random.randint(0, 2))
    print('task3:姓名,5王')
    time.sleep(random.randint(0, 2))
    print('task3:年龄,34')
    time.sleep(random.randint(0, 2))
    print('task3:性别:男')

if __name__ == '__main__':

    p1=Process(target=task1)
    p2=Process(target=task2)
    p3=Process(target=task3)

    p1.start()
    p2.start()
    p3.start()
  
运行结果如下:


从结果可以看出并发运行,效率虽然高,但并发竞争资源带来了打印信息错乱。

那么如何控制,就是加锁处理。而互斥锁的意思就是互相排斥,我们可以把多个进程比喻多个人,互斥锁的工作原理就是多个人去争抢共同的一个资源:如多个人要上同一个卫生间,一个人抢到卫生间后上一把锁,其他人都有外面等着,等到这个人完成后解锁后,其他人又可以去争夺。所以互斥锁的原题,就是把某一功能并发改串行,虽然降低了效率,但保证了数据安全不错乱。

rom  multiprocessing import Process,Lock
import random,time

def task1(lock):
    lock.acquire()#获得锁
    time.sleep(random.randint(1,3))
    print('task1:姓名,xxx')
    time.sleep(random.randint(1, 3))
    print('task1:年龄,34')
    time.sleep(random.randint(1, 3))
    print('task1:性别:男')
    lock.release()#释放锁

def task2(lock):
    lock.acquire()
    time.sleep(random.randint(1,3))
    print('task2:姓名,十三在')
    time.sleep(random.randint(1, 3))
    print('task2:年龄,34')
    time.sleep(random.randint(1, 3))
    print('task2:性别:男')
    lock.release()

def task3(lock):
    lock.acquire()
    time.sleep(random.randint(0, 2))
    print('task3:姓名,5王')
    time.sleep(random.randint(0, 2))
    print('task3:年龄,34')
    time.sleep(random.randint(0, 2))
    print('task3:性别:男')
    lock.release()

if __name__ == '__main__':
    mutex=Lock()

    p1=Process(target=task1,args=(mutex,))
    p2=Process(target=task2,args=(mutex,))
    p3=Process(target=task3,args=(mutex,))

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

运行结果如下:


这样子就不会错乱了。

强调:必须是lock.acquire()一次,然后lock.release()释放一次,才能继续lock.acquire(),不能连续的lock.acquire()

互斥锁与join()的区别:

大前提:二者的原理都是一样,都是将并发变成串行,从而保证有序

区别一:join是按照人为指定的顺序执行,而互斥锁是所有进程平等地竞争,谁先抢到谁先执行。

区别二:互斥锁可以让一部分代码(修改共享数据的代码)串行,而join只能将代码整体串行。

来看一个抢票的小例子:

# db.json文件中的内容为{"count": 100}
from multiprocessing import Process,Lock
import json ,time
import random

def search(name):
    dic=json.load(open('db.json','r',encoding='utf-8'))
    time.sleep(random.randint(0,2))#模拟网络延迟
    print('%s查到剩余的票数为%s张'%(name,dic['count']))

def get(name):
    dic = json.load(open('db.json', 'r', encoding='utf-8'))
    time.sleep(0.3)#模拟网络延迟
    if dic['count']>0:
        time.sleep(0.1)#模拟网络延迟
        print('%s成功买到了剩下的第%s票'%(name,dic['count']))
        dic['count'] -= 1
        json.dump(dic,open('db.json','w',encoding='utf-8'))

def rob_ticket(name ,lock):
    search(name)
    with lock:   #相当于获得了lock.acquire(),执行代码体完,自动执行lock.release()
        get(name)

if __name__ == '__main__':
    lock=Lock()
    for i in range(100):
        name='路人%s'%i
        p=Process(target=rob_ticket,args=(name,lock))
        p.start()

总结:



猜你喜欢

转载自blog.csdn.net/miaoqinian/article/details/80074728