26、僵尸进程&孤儿进程、守护进程、互斥锁

Day 25

一、僵尸进程与孤儿进程

孤儿进程:当父进程已经结束,而子进程还在运行,子进程就成为孤儿进程,有其存在的必要性,没有不良影响。

僵尸进程:当一个进程已经结束了,但是它仍然有一些数据存在,此时称之为僵尸进程(PID是有限的,僵尸进程过多会导致无法开启新的进程)
在linux中,有这么一个机制,父进程无论什么时候都可以获取到子进程的一些数据
子进程 任务执行完毕后,确实结束了,但是仍然保留一些数据 目的是为了让父进程能够获取这些信息
python中已经在start等功能中封装了这些操作,无需关心

二、守护进程

在python中,守护进程也是一个进程

默认情况下 主进程即使代码执行完毕了 也会等待子进程 是为了避免成为孤儿.

当一个进程b设置为另一进程a的守护进程时,a是被守护,b是守护进程

特点:当被守护的a结束时,即使b的任务没有完成也会随之结束

from multiprocessing import Process
import time


def task():
    print('son run')
    time.sleep(3)
    print('son over')


if __name__ == '__main__':
    p = Process(target=task)
    p.daemon = True  # 是布尔类型,默认为False,要在start之前
    p.start()  # 如果只运行一次可以这么写

    print('Dad')

三、进程安全问题—互斥锁

进程安全问题

当并发的多个任务,要同时操作同一个资源,就会造成数据错乱的问题

解决的方法是,将并发操作公共资源的代码 由并发变为串行 解决了安全问题,但是牺牲了效率
  • 方式一

    直接使用join函数
    缺点:将任务中所有代码全都串行,此时还是不如不要开进程
    多个进程之间原本是公平竞争,join强行规定了执行顺序

from multiprocessing import Process


def task1():
    print('name is nick')
    print('gender is girl')
    print('age is 18')


def task2():
    print('name is bgon')
    print('gender is oldman')
    print('age is 48')


if __name__ == '__main__':
    p1 = Process(target=task1)
    p2 = Process(target=task2)

    p1.start()
    p2.start()
    # p1.join()#可以解决
    # p2.join()#但是效率非常低低低,不是最好的解决方案
  • 方式二:

    互斥锁 重点

    其原理又是将要操作公共资源的代码锁起来🔒,保证同一时间只能有一个进程在执行这部分代码

    锁其实只是给执行的代码加了限制
    
from multiprocessing import Process, Lock
import time, random

mutex = Lock()  # 造锁


def task1(mutex):
    mutex.acquire()  # 加锁
    print('name is nick')
    time.sleep(random.random())
    print('gender is girl')
    time.sleep(random.random())
    print('age is 18')
    mutex.release()  # 解锁


def task2(mutex):
    mutex.acquire()  # 加锁
    print('name is bgon')
    time.sleep(random.random())
    print('gender is oldman')
    time.sleep(random.random())
    print('age is 48')
    mutex.release()  # 解锁


if __name__ == '__main__':
    p1 = Process(target=task1,args=(mutex,))
    p2 = Process(target=task2,args=(mutex,))

    p1.start()
    p2.start()
    # p1.join()#可以解决
    # p2.join()#但是效率非常低低低

四、模拟抢票小案例

from multiprocessing import Process, Lock
import json


def show():
    with open("db.json") as f:
        data = json.load(f)
        print("剩余票数", data["count"])


def buy():
    with open("db.json") as f:
        data = json.load(f)
        if data["count"] > 0:
            data["count"] -= 1
            with open("db.json", "wt") as f2:
                json.dump(data, f2)
                print("抢票成功!")


def task(mutex):
    show()
    mutex.acquire()
    buy()#对于买这个操作,增加限制
    mutex.release()


if __name__ == '__main__':
    mutex = Lock()
    for i in range(5):
        p = Process(target=task, args=(mutex,))
        p.start()
posted @ 2021-01-20 21:03  BaiM0  阅读(88)  评论(0编辑  收藏  举报