• 多进程


    重点源码

    class Process():
        name: str  --------------name名字必须是字符串
        daemon: bool
        pid: Optional[int]
        exitcode: Optional[int]
        authkey: bytes
        sentinel: int
    

    易错

    不同于深拷贝,进程的空间隔离,主进程和子进程中的不可变元素,除了数字地址是一样的,像字符串等的不遵循小数据池原理
    

    1. 进程创建的两种方式

    1. 第一种函数方式

    from multiprocessing import Process
    import time
    
    def task(name):   # 这个变量名可以改变,与下边对应即可
        print(f"{name} is running")
        time.sleep(2)
        print(f"{name} is done")
    
    if __name__ == "__main__":
        #在Windows环境下,开启进程必须在__name__ == "__main__"下面
        #此模块与windows某些地方有冲突
        print(666)
        p = Process(target=task,args=("太白",))  #args必须接受一个元祖
        p.start()
        # 只是向操作系统发出一个开辟子进程的信号,然后就执行下一行了,
        # 将p这个进程放进去(copy主进程),然后让CPU去执行
        #只复制了if条件语句的上边部分
        print("==主")
    
    • 注意
      1. task函数名可以改变,与下边对应即可
      2. Windows环境下,开启进程必须在测试端口
      3. args传的值必须以元组形式,并且传的值要传的值一一对应
      4. p处只是提示操作系统开辟子进程,然后就继续执行了
      5. 子进程复制的只是if语句上边的内容

    2. 第二种执行类方法

    from multiprocessing import Process
    import time
    
    class MyProcess(Process):  # 必须继承Process,类名可以换
        
        def __init__(self,name):
            super().__init__()  #必须继承父类的__init__方法
            #原因在于父类的init还封装着别的参数,必须继承
            self.name = name
    
        def run(self):
            #必须要写成run方法,改了名字默认继承父类,pass,结果就只执行主进程
            print(f"{self.name} is running")
            time.sleep(2)
            print(f"{self.name} is done")
    
    if __name__ == "__main__":
        p = MyProcess("太白")
        p.start()
        print("==主")
    

    注意

    1. 此类必须继承Process
    2. 传值情况下必须继承父类的__init__方法
    3. 类方法必须是run,如果改了名字只会执行父类
    4. self.name 默认等于 MyProcess-1
    5. 必须继承父类的__init__方法,原因在于父类的init还封装着别的参数,必须继承
    class MyProcess(Process):  # 必须继承Process,类名可以换
    
        def run(self):
            # 必须要写成run方法,改了名字默认继承父类,pass,结果就只执行主进程
            print(f"{self.name} is running")
            time.sleep(2)
            print(f"{self.name} is done")  #默认继承父类的init方法
    
    if __name__ == "__main__":
        p = MyProcess()
        p.start()
        print("==主")
    
    # 结果:
    # ==主
    # MyProcess-1 is running
    # MyProcess-1 is done
    

    2.进程的简单应用

    1. 串行:所有的任务一个一个的完成(相当于调用三个函数)

    from multiprocessing import Process
    import time
    
    def task(name):
        print(f"{name} is running")
        time.sleep(2)
        print(f"{name} is done")
    
    def task1(name):
        print(f"{name} is running")
        time.sleep(3)
        print(f"{name} is done")
    
    def task2(name):
        print(f"{name} is running")
        time.sleep(1)
        print(f"{name} is done")
    
    if __name__ == "__main__":
        start_time = time.time()
        task("太白")
        task1("宝元")
        task2("女神")
        print(f"运行时间为:{time.time() - start_time}")
    
    """
    太白 is running
    太白 is done
    宝元 is running
    宝元 is done
    女神 is running
    女神 is done
    运行时间为:6.001795053482056
    """
    

    2. 并发:一个CPU完成多个任务,看起来像是同时完成

    并行:多个CPU执行多个任务,真正的同时完成

    from multiprocessing import Process
    import time
    
    def task(name):
        print(f"{name} is running")
        time.sleep(3)
        print(f"{name} is done")
    
    def task1(name):
        print(f"{name} is running")
        time.sleep(2)
        print(f"{name} is done")
    
    def task2(name):
        print(f"{name} is running")
        time.sleep(5)
        print(f"{name} is done")
    
    if __name__ == "__main__":
        start_time = time.time()
        p = Process(target=task,args=("太白",))  # 创建一个进程对象
        p1 = Process(target=task1,args=("宝元",))  # 创建一个进程对象
    
        p.start()   #只提示创建就往下走了
        p1.start()  #
        task2("女神") #第一个打印
        print(f"运行时间为:{time.time() - start_time}")#必须等task2执行完
    
    """
    女神 is running
    太白 is running
    宝元 is running
    宝元 is done
    太白 is done
    女神 is done
    运行时间为:5.075502872467041
    """
    
    from multiprocessing import Process
    import time
    
    def task(name):
        print(f"{name} is running")
        time.sleep(3)
        print(f"{name} is done")
    
    def task1(name):
        print(f"{name} is running")
        time.sleep(1)
        print(f"{name} is done")
    
    def task2(name):
        print(f"{name} is running")
        time.sleep(2)
        print(f"{name} is done")
    
    if __name__ == "__main__":
        start_time = time.time()
        p = Process(target=task,args=("太白",))  # 创建一个进程对象
        p1 = Process(target=task1,args=("宝元",))  # 创建一个进程对象
        p2 = Process(target=task1,args=("女神",))  # 创建一个进程对象
    
        p.start()
        p1.start()
        p2.start()
        print(f"运行时间为:{time.time() - start_time}")
    
    """
    运行时间为:0.12958216667175293
    太白 is running
    宝元 is running
    女神 is running
    宝元 is done
    女神 is done
    太白 is done
    """
    

    ![

    3. pid是进程在内存中的唯一标识

    在cmd终端输入tasklist查询所有进程的pid
    在cmd终端输入tasklist|findstr python查询pycharm中多个进程的pid
    在cmd终端输入tasklist|findstr pycharm查询主进程的pid
    (在pycharm文件未关闭的前提下才可以找到)
    

    具体操作如下

    1. 如何区分内存中的这些进程?

      • cmd终端获取所有的进程的pid 方法 tasklist
      • 1566291404490
    2. 代码级别如果获取一个进程pid

      • cmd终端获取所有子进程的pid 方法 tasklist|findstr python

      • ![

      • ![

      • import os
        import time
        print(f"子进程:{os.getpid()}")
        time.sleep(50) #关闭了在内存中就看不到了
        
      • cmd终端获取所有主进程的pid 方法 tasklist|findstr pycharm

      • ![

        ![

      import os
      import time
      print(f"主进程:{os.getppid()}")
      time.sleep(50) #关闭了在内存中就看不到了
      
      from multiprocessing import Process
      import os
      
      def task():
          print(f"子进程:{os.getpid()}")   #子进程pid
          print(f"主进程:{os.getppid()}")  #主进程pid
      
      if __name__ == "__main__":
          p = Process(target=task)
          p.start()
          print(f"==主进程{os.getpid()}")  #进程pid
      
      

    4. 验证进程之间的空间隔离

    1. 主进程为不可变数据类型 : 主不变(空间隔离了,没有关系了)

    子进程只是初始数据复制主进程的内容

    from multiprocessing import Process
    import time
    name = "太白"
    def task():
        global name
        name = "alexsb"
        print(f"子进程:{name}")
    
    if __name__ == "__main__":
        p = Process(target=task)  
        p.start()  #开辟一个子进程空间,
        print(f"==主:{name}")  #空间隔离,不会变
        time.sleep(2)
        print(f"==主:{name}")  #空间隔离,不会变
    

    2. 主进程为可变数据类型 : 主不变(空间隔离了,没有关系了)

    子进程只是初始数据复制主进程的内容

    from multiprocessing import Process
    import time
    lst = ["太白"]
    def task():
        lst.append("alexsb")
        print(f"子进程:{lst}")
    
    if __name__ == "__main__":
        p = Process(target=task)
        p.start()  #开辟一个子进程空间,
        print(f"==主:{lst}")  #空间隔离,不会变
        time.sleep(2)
        print(f"==主:{lst}")  #空间隔离,不会变
    

    5. 进程的 join 阻塞 让主进程等待子进程结束之后,在执行主进程

    (join后边的主进程内容被阻塞)

    1. 一个子进程之间的主进程阻塞

    from multiprocessing import Process
    import time
    
    def task(name):
        print(f"{name} is running")
        time.sleep(2)
        print(f"{name} is gone")
    
    if __name__ == "__main__":
        start_time = time.time()
        p = Process(target=task,args=("太白",)) #创建一个子进程对象
        p.start()
        p.join() #产生阻塞
        print(f"==主:{time.time()-start_time}")  #上边阻塞,要等待子进程执行完毕才执行
    
    1. 多个子进程之间的主进程阻塞

    from multiprocessing import Process
    import time
    
    def task(name,sec):
        print(f"{name} is running")
        time.sleep(sec)
        print(f"{name} is gone")
    
    if __name__ == "__main__":
        start_time = time.time()
        p = Process(target=task,args=("太白",2))
        p1 = Process(target=task,args=("宝元",3))
        p2 = Process(target=task,args=("日天",1))
    
        #以下三个几乎同时进行
        p.start()
        p1.start()
        p2.start()
    
        #多重阻塞
        p.join()
        print(f"==主1:{time.time() - start_time}")
        p1.join()
        print(f"==主2:{time.time() - start_time}")
        p2.join()
        print(f"==主3:{time.time() - start_time}")
    """
    太白 is running
    宝元 is running
    日天 is running
    日天 is gone
    太白 is gone
    ==主1:2.1800968647003174
    宝元 is gone
    ==主2:3.1918866634368896
    ==主3:3.1918866634368896
    """
    

    3. 优化代码下列代码

    from multiprocessing import Process
    import time
    
    def task(sec):
        print(f'is running')
        time.sleep(sec)
        print(f' is gone')
    
    
    if __name__ == '__main__':
        start_time = time.time()
        p1 = Process(target=task,args=(1,))
        p2 = Process(target=task,args=(2,))
        p3 = Process(target=task,args=(3,))
    
        p1.start()
        p2.start()
        p3.start()
    
        p1.join()
        p2.join()
        p3.join()
    
    from multiprocessing import Process
    import time
    
    def task(sec):
        print(f'is running')
        time.sleep(sec)
        print(f' is gone')
    
    if __name__ == '__main__':
        start_time = time.time()
        lst = []
        for i in range(1,4):
            p = Process(target=task, args=(i,))
            lst.append(p)
            p.start()
        for i in lst:
            i.join()
        print(f"==主:{time.time() - start_time}")
    

    6.进程的其他参数

    1. p.terminate() 杀死子进程(快速的话子进程不会执行)

    from multiprocessing import Process
    import time
    
    def task(name):
       print(f"{name} is going")
       time.sleep(2)
       print(f"{name} is done")
    
    if __name__ == "__main__":
        p = Process(target=task,args=("太白",))
    
        p.start()
        #time.sleep(1)
        p.terminate()  #杀死子进程,可以添加睡的时间选择让子进程执行一半时杀死
        print("==主开始")
    

    2. p.is_alive() 判断子进程是否还活着(True,False)

    from multiprocessing import Process
    import time
    
    def task(name):
       print(f"{name} is going")
       time.sleep(2)
       print(f"{name} is done")
    
    if __name__ == "__main__":
        p = Process(target=task,args=("太白",))
    
        p.start()
        p.terminate()  #杀死子进程(需要点时间传递)
        # p.join()
        # time.sleep(1)
        print(p.is_alive()) #上方如果不加阻塞代码,时间太短,结果是False
        print("==主开始")
    
    

    3. p.name() 给实例化对象封装name属性,默认为类名-1

     p = Process(target=task,args=("太白",),name = "alex)
    

    7. 守护进程 子进程守护着主进程,只要主进程结束,子进程跟着就结束

    from multiprocessing import Process
    import time
    
    def task(name):
        print(f"{name} is running")
        time.sleep(2)
        print(f"{name} is done")
    
    if __name__ == "__main__":
        p = Process(target=task,args=("太白",))
        p.daemon = True  #主进程结束,子进程就结束了
        p.start()
        # time.sleep(1)
        # p.daemon = True  # 一定要在子进程开启之前设置
        print("==主")
    
  • 相关阅读:
    CentOS7使用firewalld打开关闭防火墙与端口
    ssh连接卡在【To escape to local shell, press 'Ctrl+Alt+]'.】的解决方法
    本地链路地址
    RIFF和WAVE音频文件格式
    声音分贝的概念,dBSPL.dBm,dBu,dBV,dBFS
    VS中C++ 项目重命名
    FFmpeg学习6:视音频同步
    FFmpeg学习5:多线程播放视音频
    FFmpeg学习4:音频格式转换
    FFmpeg数据结构:AVPacket解析
  • 原文地址:https://www.cnblogs.com/lvweihe/p/11385623.html
Copyright © 2020-2023  润新知