zoukankan      html  css  js  c++  java
  • python并发编程02 /多进程、进程的创建、进程PID、join方法、进程对象属性、守护进程

    python并发编程02 /多进程、进程的创建、进程PID、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__':
          p = Process(target=task,args=('张三',))   # 创建一个进程对象
          p.start()
          print('==主开始')
        
          
      # 1.在window环境下,开启进程必须__name=='__main__'下面
      #   原因:这是 Windows 上多进程的实现问题。在 Windows 上,子进程会自动 import 启动它的这个文件,而在 import 的时候是会执行这些语句的。如果你这么写的话就会无限递归创建子进程报错。所以必须把创建子进程的部分用那个 if 判断保护起来,import 的时候 __name__ 不是 __main__ ,就不会递归运行了。
      
      # 2.p.start()
      #   只是向操作系统发出一个开辟子进程的信号,然后就执行下一行了,这个信号操作系统接收到之后,会从内存中开辟子进程空间,然后再将主进程所有数据copy加载到子进程,然后再调用CPU去执行.
      
      # 3.开辟子进程开销是很大的,所以永远会先执行主进程的代码
      
    • 开启进程的第二种方式

      from multiprocessing import Process
      import time
      
      class MyProcess(Process):
      
          def __init__(self,name):
              super().__init__()
              self.name = name
      
          def run(self):
              print(f'{self.name} is running')
              time.sleep(2)
              print(f'{self.name} is gone')
      
      
      if __name__ == '__main__':
          p = MyProcess('张三')
          p.start()
          print('===主')
      
    • 简单应用

      from multiprocessing import Process
      import time
      
      def task(name):
          print(f'{name} is running')
          time.sleep(1)
          print(f'{name} is gone')
      
      def task1(name):
          print(f'{name} is running')
          time.sleep(2)
          print(f'{name} is gone')
      
      def task2(name):
          print(f'{name} is running')
          time.sleep(3)
          print(f'{name} is gone')
      
      
      if __name__ == '__main__':
          # 一个进程串行的执行三个任务
          start_time = time.time()
          task('张三')
          task1('李四')
          task2('王五')
          print(f'结束时间{time.time() - start_time}')
          
          # 三个进程 并发或者并行的执行三个任务
          start_time = time.time()
          p1 = Process(target=task, args=('李四',))   # 创建一个进程对象
          p2 = Process(target=task1, args=('王五',))  # 创建一个进程对象
          p1.start()
          p2.start()
          task2('张三')
          print(f'结束时间{time.time()-start_time}')
      

    2. 进程PID

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

    • pid的获取:

      命令行获取所有的进程的pid:tasklist;命令行获取某个进程的pid:tasklist|findstr python

      代码级别获取一个进程的pid

      import os
      print(os.getpid())
      

      获取父进程(主进程)的pid

      import os
      print(f'子进程:{os.getpid()}')
      print(f'主(父)进程:{os.getppid(())}')
      
    • 验证进程之间的空间隔离

      from multiprocessing import Process
      import time
      name = '张三'
      
      def task():
          global name
          name = '李四'
          print(f'子进程{name}')
      
      
      if __name__ == '__main__':
          p = Process(target=task)  # 创建一个进程对象
          p.start()
          # print('==主开始')
          time.sleep(3)
          print(f'主:{name}')
          
      # 不能共享内存的数据
      

    3. 进程对象join方法

    • join让主进程等待子进程结束后,再执行主进程(lock,队列)

    • 示例一:简单使用

      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__':
      
          p = Process(target=task,args=('太阳',))  # 创建一个进程对象
          p.start()
          p.join()
          print('==主开始')
      
    • 示例二:多个子进程使用join

      # 未使用join耗时
      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()
          p1 = Process(target=task,args=('太阳',1))
          p2 = Process(target=task,args=('月亮',2))
          p3 = Process(target=task,args=('星星',3))
          p1.start()
          p2.start()
          p3.start()
          print(f'==主{time.time()-start_time}')  # 0.02 这只是主进程结束的时间,与其他进程毫无关系
          
      # 验证1:使用join,测试多个join之后的结果以及耗时
      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()
          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()
          print(f'==主{time.time()-start_time}')
      
      # 结果:
      张三is running
      李四is running
      王五is running
      张三 is gone
      李四 is gone
      王五 is gone
      ==主3.2888922691345215
      
      # 验证2:使用join,测试多个join之后的结果以及每个join之后的耗时
      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()
          p1 = Process(target=task,args=('张三',3))
          p2 = Process(target=task,args=('李四',2))
          p3 = Process(target=task,args=('王五',1))
      
          p1.start()
          p2.start()
          p3.start()
          p1.join()
          print(f'==主1:{time.time()-start_time}')
          p2.join()
          print(f'==主2:{time.time()-start_time}')
          p3.join()
          print(f'==主3:{time.time()-start_time}') 
          
      # 结果:
      张三is running
      李四is running
      王五is running
      张三 is gone
      李四 is gone
      王五 is gone
      ==主1:3.2728402614593506
      ==主2:3.2728402614593506
      ==主3:3.2728402614593506
      
    • 优化使用多个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()
          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()
          
          # 错误示范:这样就是串行,一个执行完执行下一个
          for i in range(1,4):
              p = Process(target=task,args=(i,))
              p.start()
              p.join()
          p1 = Process(target=task,args=(1,))
          p1.start()
          p1.join()
          p2 = Process(target=task,args=(2,))
          p2.start()
          p2.join()
          p3 = Process(target=task,args=(3,))
          p3.start()
          p3.join()
      
          
          # 正确示范:
          l1 = []
          for i in range(1, 4):
              p = Process(target=task,args=(i,))
              l1.append(p)
              p.start()
          
          for i in l1:
              i.join()
          
          print(f'==主{time.time()-start_time}')
      
      # join就是阻塞,主进程有join,主进程下面的代码一律不执行,直到进程执行完毕之后,再执行.
      

    4. 进程对象其他属性

    • 常见属性释义:

      p.terminate() :杀死子进程

      print(p.is_alive()) :判断子进程是否存活

      p.name = '子进程2' :给子进程设置名称

    • 代码示例:terminate/is_alive/p.name

      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__':
           p = Process(target=task,args=('张三',),name='子进程')  # 创建一个进程对象,其中的name='子进程'是给该进程设置名字为子进程
          p.start()
          time.sleep(1)
          p.terminate()    # 杀死子进程  ***
          p.join()  # ***
          time.sleep(0.5)
          print(p.is_alive())   # 判断子进程是否存活 ***
          print(p.name)
          p.name = '子进程2'    # 给子进程设置名称
          print(p.name)
          print(p.pid)         # 查看pid
          print('==主开始')
      

    5. 守护进程

    • 守护进程:子进程守护着主进程,只要主进程结束,子进程就跟着结束

    • 代码示例:

      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__':
          p = Process(target=task,args=('太阳',))  # 创建一个进程对象
          p.daemon = True  # 将p子进程设置成守护进程,只要主进程结束,守护进程马上结束.
          p.start()
          # p.daemon = True  # 一定要在子进程开启之前设置
          time.sleep(1)
          print('===主')
      
  • 相关阅读:
    str_replace函数的使用规则和案例详解
    phpqrcode.php 生成二维码图片用于推广
    常用的正则表达式验证
    Java:原生javaWeb下载pdf文件
    设计模式:七大原则
    Spring Boot:整合Hikari+Oracle+p6spy
    Spring Boot:开启全局事务
    Java8:按照对象的属性,对List集合分组
    SpringMVC统一异常处理
    JSR303校验的基本使用和结合AOP使用
  • 原文地址:https://www.cnblogs.com/liubing8/p/11386143.html
Copyright © 2011-2022 走看看