Python学习的第36天进程之守护进程、互斥锁

一、守护进程:

1、守护进程: 本质就是一个"子进程",该"子进程"的生命周期<=被守护进程的生命周期,当一个进程作为守护进程时 被被守护的进程死亡时 守护进程也跟随死亡

2、使用

from multiprocessing import Process
import time

def task(name):
    print('老太监%s活着....' %name)
    time.sleep(3)
    print('老太监%s正常死亡....' %name)

if __name__ == '__main__':
    p=Process(target=task,args=('刘清政',))
    p.daemon=True       #一定要在p.start()前设置, 设置p为守护进程, 禁止p创建子进程, 并且父进程代码执行结束, p即终止运行
 p.start() time.sleep(1) print('皇上:EGON正在死...')    # 只要终端打印出这一行内容, 那么守护进程p也就跟着结束掉了

二、互斥锁

1、为什么要用互斥锁:

在内存中进程之间是被物理隔开的,进程之间数据不共享,要是想共享数据只能从它们公有的资源硬盘(文件)的读写来实行,但是有个问题:虽然进程们可以一起读取文件,但是当一起写文件的时候会出现资源的竞争,都会抢着去写文件,竞争带来的结果是错乱,如下:多个进程模拟多个人执行抢票任务

 db.json文件内容:
{"count": 1}

import json, time, random
from multiprocessing import Process

def search(name):
    with open("db.json", "rt", encoding="utf-8") as f:
        dic = json.load(f)
    time.sleep(1)   # 模拟查看票数的网络延迟
    print("%s查看到余票为%s张" %(name, dic["count"]))

def get(name):
    with open("db.json", "rt", encoding="utf-8") as f:
        dic = json.load(f)
    if dic["count"] > 0:
        dic["count"] -= 1
        time.sleep(random.randint(1, 3))    # 模拟买票的网络延迟

        with open("db.json", "wt", encoding="utf-8") as f:
            json.dump(dic, f)
            print("%s购票成功" %name)
    else:
        print("%s查看到没有票了" %name)

def task(name):
    search(name)
    get(name)

if __name__ == '__main__':
    for i in range(10):
        p = Process(target=task, args=("路人%s " %i,))
        p.start()

# 运行结果
路人0 查看到余票为1张
路人1 查看到余票为1张
路人2 查看到余票为1张
路人3 查看到余票为1张
路人4 查看到余票为1张
路人5 查看到余票为1张
路人6 查看到余票为1张
路人7 查看到余票为1张
路人9 查看到余票为1张
路人8 查看到余票为1张
路人0 购票成功
路人3 购票成功
路人4 购票成功
路人7 购票成功
路人9 购票成功
路人1 购票成功
路人2 购票成功
路人6 购票成功
路人8 购票成功
路人5 购票成功

可以看到,它们10个人是并发运行,效率高,但竞争写同一文件,数据写入错乱,只有一张票,却成功卖给了10个人。之前学到 join,但 join 的操作相当于指定了买票的顺序,只能由第一个人买,并不能保证数据的安全性。

所以要进行加锁处理。而互斥锁的意思就是互相排斥,如果把多个进程比喻为多个人,互斥锁的工作原理就是多个人都要去争抢同一个资源:卫生间,一个人抢到卫生间后上一把锁,其他人都要等着,等到这个完成任务后释放锁,其他人才有可能有一个抢到......所以互斥锁的原理,就是把部分的并发改成串行,降低了效率,但保证了数据安全不错乱

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

def search(name):
    with open("db.json", "rt", encoding="utf-8") as f:
        dic = json.load(f)
    time.sleep(1)   # 模拟查看票数的网络延迟
    print("%s查看到余票为%s张" %(name, dic["count"]))

def get(name):
    with open("db.json", "rt", encoding="utf-8") as f:
        dic = json.load(f)
    if dic["count"] > 0:
        dic["count"] -= 1
        time.sleep(random.randint(1, 3))    # 模拟买票的网络延迟

        with open("db.json", "wt", encoding="utf-8") as f:
            json.dump(dic, f)
            print("%s 购票成功" %name)
    else:
        print("%s 查看到没有票了" %name)

def task(name, mutex):
    search(name)    # 并发
    mutex.acquire()     # 加锁
    get(name)       # 串行
    mutex.release()     # 释放锁

    # with mutex:   # 相当于mutex.acquire(),执行完子代码块自动执行mutex.release()
    #     get(name)

if __name__ == '__main__':
    mutex = Lock()
    for i in range(10):
        p = Process(target=task, args=("路人%s " %i, mutex))
        p.start()

# 运行结果
路人0 查看到余票为1张
路人1 查看到余票为1张
路人3 查看到余票为1张
路人2 查看到余票为1张
路人4 查看到余票为1张
路人5 查看到余票为1张
路人6 查看到余票为1张
路人7 查看到余票为1张
路人8 查看到余票为1张
路人9 查看到余票为1张
路人0  购票成功
路人1  查看到没有票了
路人3  查看到没有票了
路人2  查看到没有票了
路人4  查看到没有票了
路人5  查看到没有票了
路人6  查看到没有票了
路人7  查看到没有票了
路人8  查看到没有票了
路人9  查看到没有票了

猜你喜欢

转载自www.cnblogs.com/ye-hui/p/9936923.html