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('===主')

python并发编程02 /多进程、进程的创建、进程PID、join方法、进程对象属性、守护进程的更多相关文章

  1. Python进阶(4)_进程与线程 (python并发编程之多进程)

    一.python并发编程之多进程 1.1 multiprocessing模块介绍 由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大 ...

  2. Python并发编程__多进程

    Python并发编程_多进程 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大 ...

  3. python并发编程之多进程基础知识点

    1.操作系统 位于硬件与应用软件之间,本质也是一种软件,由系统内核和系统接口组成 和进程之间的关系是: 进程只能由操作系统创建 和普通软件区别: 操作系统是真正的控制硬件 应用程序实际在调用操作系统提 ...

  4. Python - 并发编程,多进程,多线程

    传送门 https://blog.csdn.net/jackfrued/article/details/79717727 在此基础上实践和改编某些点 1. 并发编程 实现让程序同时执行多个任务也就是常 ...

  5. Python并发编程之多进程(实战)

    一.multiprocessing和Process multiprocessing提供了支持子进程.通信和数据共享.执行不同形式的同步,提供了Process.Queue.Pipe.Lock等组件 创建 ...

  6. python并发编程之多进程(三):共享数据&进程池

    一,共享数据 展望未来,基于消息传递的并发编程是大势所趋 即便是使用线程,推荐做法也是将程序设计为大量独立的线程集合 通过消息队列交换数据.这样极大地减少了对使用锁定和其他同步手段的需求, 还可以扩展 ...

  7. python并发编程之多进程(二):互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  8. python并发编程之多进程1-----------互斥锁与进程间的通信

    一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...

  9. python并发编程之多进程2-------------数据共享及进程池和回调函数

    一.数据共享 1.进程间的通信应该尽量避免共享数据的方式 2.进程间的数据是独立的,可以借助队列或管道实现通信,二者都是基于消息传递的. 虽然进程间数据独立,但可以用过Manager实现数据共享,事实 ...

随机推荐

  1. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(11.0)- FlexSPI NOR启动时间(RT1170)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT1170 FlexSPI NOR启动时间. 痞子衡刚刚拿到i.MXRT1170 B0版本的芯片,迫不及待地在上面跑了 ...

  2. Spark GraphX从入门到实战

      第1章 Spark GraphX 概述 1.1 什么是 Spark GraphX   Spark GraphX 是一个分布式图处理框架,它是基于 Spark 平台提供对图计算和图挖掘简洁易用的而丰 ...

  3. python中turtle模块画正多边形

    画正多边形主要是计算多边形每个角度对应的外角的度数,计算出来这个度数即可画图,相对来说非常简单 以正六边形为例 import turtle import time t = turtle.Pen() f ...

  4. (九)logback.xml文件配置(按时间、文件大小和log名称生成日志)

    原文链接:https://www.cnblogs.com/hhhshct/p/9084036.html rollingPolicy 设置:<rollingPolicy class="c ...

  5. css方法1(清除ul边距间隙,两端对齐,字母大写,首字放大)

    一.清除ul自带左边间距 ul{ margin:; padding:; } 二.ul li 与li  之间隙 1.ul 设置font-size:0 ; 子li 设置字体大小 2.把li写到一起,不换行 ...

  6. win10 VirtualBox无法打开,COM对象创建失败

    https://blog.csdn.net/txwtech/article/details/101900464 VirtualBox无法打开,打开后提示创建COM对象失败: 被召者 RC: E_NOI ...

  7. 高性能IO —— Reactor(反应器)模式

    讲到高性能IO绕不开Reactor模式,它是大多数IO相关组件如Netty.Redis在使用的IO模式, 为什么需要这种模式,它是如何设计来解决高性能并发的呢? 最最原始的网络编程思路就是服务器用一个 ...

  8. robot framework使用小结(二)

    robot framework关键字驱动采用分层,结合Template做成数据驱动 我个人觉得不管是关键字驱动还是数据驱动,都是基于模块(或者是函数)的概念 新建测试案例baidu02,添加Libra ...

  9. 入门大数据---Redis集群分布式学习

    Redis是什么? 官方介绍: Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 字符串(strings), 散列( ...

  10. Spring WebFlux 01 (原理及使用场景)

    一.什么是 Spring WebFlux 好多人以为Spring WebFlux就是Spring MVC的升级版,其实不然,那到底什么是Spring WebFlux呢,首先就要搞清楚Spring We ...