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. JavaScript 定时器 取消定时器

    感谢:链接(视频讲解很清晰) 定时器:作用主要是一定时间间隔后,做出相关的变化,例如图片轮播. 目录 两种定时器的使用 两种定时器区别 取消定时器的方法 两种定时器的使用: 方法一:setTimeou ...

  2. 使用阿里云K8S 服务,丢失访问中原始IP 问题

    解决步骤: 1. 利用kubectl 修改 k8s 配置, 设置 external** = Local 2. 在服务发现与负载均衡界面,选择对应的LB 服务, 设置服务LB 的 external** ...

  3. charles 破解方法

    1.https://www.charlesproxy.com/latest-release/download.do 官网下载charles 2.傻瓜式安装完成(路径可以默认c盘) 3.安装完成后去c盘 ...

  4. 深入理解 EF Core:EF Core 读取数据时发生了什么?

    阅读本文大概需要 11 分钟. 原文:https://bit.ly/2UMiDLb 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能 ...

  5. 研华advantech-凌华ADLINK板卡运动控制卡

    研华advantech:6路独立D/A输出12位分辨率双缓冲D/A转换器多种电压范围:+/-10V,+/-5V,0—+5V,0—+10V和4—20mA电流环(汇)16路数字量输入及16路数字量输出 P ...

  6. 挖洞入门_显错型SQL注入

    简介:在漏洞盒子挖洞已经有一段时间了,虽说还不是大佬,但技术也有所进步,安全行业就是这样,只有自己动手去做,才能将理论的知识变为个人的经验.本篇文章打算分享一下我在挖显错型SQL注入漏洞过程中的一些个 ...

  7. Mysql报错Error Code: 1175. You are using safe update

    使用MySQL执行update的时候报错:Error Code: 1175. You are using safe update mode and you tried to update a tabl ...

  8. JavaWeb网上图书商城完整项目--day02-4.regist页面提交表单时对所有输入框进行校验

    1.现在我们要将table表中的输入的参数全部提交到后台进行校验,我们提交我们是按照表单的形式提交,所以我们首先需要在table表外面添加一个表单 <%@ page language=" ...

  9. django python mange.py runserver 源码

    django python mange.py runserver 源码 入 口 mange.py文件 execute_from_command_line函数 输入参数为['manage.py', 'r ...

  10. 【C++和C#的区别杂谈】后自增运算符的结算时机

    C++和C#的前自增++n和后自增n++,都是先自增后取值和先取值后自增的含义,但在复杂一点的赋值语句中,我发现细节上有很大的差异. 发现这个问题主要是一个无聊的晚上,我想搞清楚后自增是什么时候结算, ...