• 进程


    守护进程 了解

    什么是守护进程

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

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

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

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

    案例:

    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:

    直接使用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

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

    锁的 粒度

    粒度指的是被锁住的代码的多少

    粒度越大锁住的越多 效率越低

    互斥锁的案例:

    抢票

    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()
    

    IPC

    Inter-Process Communication

    空间复用 中内存隔离开了多个进程直接不能直接交互

    IPC指的就是进程间通讯

    几种方式 :

    1.创建一个共享文件

    ​ 缺点: 效率较低

    ​ 优点: 理论上交换的数据量可以非常大

    ​ 适用于: 交互不频繁 且数据量较大的情况

    2.共享内存 (主要方式)

    ​ 缺点: 数据量不能太大

    ​ 优点: 效率高

    ​ 适用于: 交互频繁,但是数据量小

    3.管道

    ​ 管道也是基于文件的 它是单向的 编程比较复杂

    4.socket

    ​ 编程复杂,更适用于基于网络来交换数据

    共享内存的第一种方式

    Manger

    可以为我们创建 进程间同步的容器,但是没有处理安全问题 ,所以并不常用

    Queue

    Queue 翻译为队列 是一种特殊的容器 特殊之处在于存取顺序为先进先出

    可以帮我们完成进程间通讯

    from multiprocessing import Queue
    
    q = Queue(2) # 创建队列 并且同时只能存储2个元素
    q.put(1)
    q.put(2)
    
    # q.put(3,block=True,timeout=3) # 默认是阻塞的 当容器中没有位置了就阻塞 直到有人从里面取走元素为止
    print(q.get())
    print(q.get())
    print(q.get(block=True,timeout=3))# 默认是阻塞的 当容器中没有位置了就阻塞 直到有人存入元素为止
    

    扩展: 栈

    也是一种特殊的容器 特殊在于 存取顺序为 先进后出

    函数调用栈

    调用函数时 称之为 函数入栈

    函数执行结束 称之为函数出栈

  • 相关阅读:
    Solaris 11 system package 安装与更新(如:assembler)
    JS实现页面内跳转
    使用Eclipse进行嵌入式软件开发
    Eclipse下C++标准库报错::mbstate_t has not been declared
    嵌入式ARM开发环境搭建
    CCS内存数据转成图片
    RESET
    Android 圆角研究
    Java 重写必须满足的条件
    android 社会化分享集成
  • 原文地址:https://www.cnblogs.com/zhuyuanying123--/p/11133220.html
Copyright © 2020-2023  润新知