守护进程及进程数据安全问题分析

一、守护进程

1、概念

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

默认情况下 主进程即使代码执行完毕了 也会等待子进程结束才会结束自己

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

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

2、比喻:

康熙 是一个进程 妃子是康熙的守护进程

康熙驾崩了 如果妃子还活着 那就陪葬去 当然如果妃子的任务提前结束了那就立即挂了

3、案例:

from multiprocessing import Process
import time
def task():
    print("zi run")
    time.sleep(3)
    print("zi over")
if __name__ == '__main__':
    p = Process(target=task)
    p.daemon = True  # 将这个进程设置为了守护进程  必须在开启进程前设置
    p.start()
    print("主over")

二、进程安全问题

1、产生原因

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

2、解决的方法

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

方法1:串行方式(join):

直接使用join函数

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

方法2:串行方式(互斥锁)

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

互斥锁是什么

互相排斥的锁

优点: 可以仅将部分代码串行

注意: 必须保证锁只有一把

使用方式:
from multiprocessing import Process,Lock
import time,random

def task1(mutex):
    # 假设这不是访问公共资源 那么还可也并发执行
    for i in range(10000):
        print(1)

    mutex.acquire() # 这是加锁
    time.sleep(random.random())
    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):
    for i in range(10000):
        print(2)

    mutex.acquire()
    time.sleep(random.random())
    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__':
    mutex = Lock()  # 创建一把互斥锁
    print("创建锁了!!!!")

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

    p1.start()
    p2.start()

加锁 解决了安全问题 带来了效率降低的问题

锁其实只是给执行代码加了限制 本质是一个标志 为True 或False

如何使得即保证安全 又提高效率

锁的 粒度   
粒度指的是被锁住的代码的多少   
粒度越大锁住的越多 效率越低 

3、互斥锁的案例:

抢票

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 @ 2019-07-04 19:03  emos  阅读(418)  评论(0编辑  收藏  举报