多进程

1. 进程创建的两种方式 multiprocessing

# 第一种方式
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__': # 在Windows环境下,必须在main下开启子进程
p = Process(target=task, args=('meet',)) # args元组形式 创建一个进程对象
p.start()
print("===主进程") """
结果:
===主进程
meet is running
meet is done
""" # p.start():开启子进程的命令,通知操作系统在内存中开辟一个进程空间,将主进程的数据copy加载到子进程空间中,然后操作系统调用cpu去执行子进程。 开销较大,因此会先执行主进程的代码。
# 第二种方式
from multiprocessing import Process
import time class MyProcess(Process): def __init__(self, name):
super().__init__() # 重构父类的方法
self.name = name
def run(self): # 必须写run()
print(f'{self.name} is running')
time.sleep(2)
print(f"{self.name} is gone") if __name__ == '__main__':
p = MyProcess('meet') # 默认执行run()
p.start() # 开启子进程的命令
print("===主进程")

2. 进程pid (process id)

进程在内存中的唯一标识。

终端命令: tasklist # 查看计算机当前所有进程的pid

终端命令: tasklist|findstr pycharm # 查看pycharm的pid

代码 :

import os
print(os.getpid()) # 查看当前进程的pid print(os.getppid()) # 查看父进程的pid

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

from multiprocessing import Process

lst = [1, 2]
def task():
lst.append(3)
print(f'子进程的:{lst}') if __name__ == '__main__':
p = Process(target=task)
p.start()
print(f'主进程的:{lst}')
"""
主进程的:[1, 2]
子进程的:[1, 2, 3]
"""
# 主进程与子进程之间存在空间隔离。

4. 进程对象join方法

join :让主进程等待子进程结束之后,再执行主进程。(让主进程阻塞)
from multiprocessing import Process
import time def task(sec):
print('is running')
time.sleep(sec)
print('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()
print(f'p1时间:{time.time()-start_time}') # 1s多
p2.join()
print(f'p2时间:{time.time()-start_time}') # 2s多
p3.join()
print(f'p3时间:{time.time()-start_time}') # 3s多
from multiprocessing import Process
import time def task(sec):
print('is running')
time.sleep(sec)
print('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'p1时间:{time.time()-start_time}') # 3s多 #阻塞
p2.join()
print(f'p2时间:{time.time()-start_time}') # 3s多
p3.join()
print(f'p3时间:{time.time()-start_time}') # 3s多
# 面试题:将下面代码优化
from multiprocessing import Process
import time def task(sec):
print('is running')
time.sleep(sec)
print('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}') # 3s多 # 上面代码优化:
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}') # 错误的优化:
for i in range(1,4)
p = Process(target=task, args=(i,))
p.start()
p.join()
print(f'运行时间:{time.time()-start_time}')

5. 进程对象其他属性

p.terminate()		# 结束子进程

p.is_alive()		# 判断子进程是否活着 True/False

p = Process(target=task, args=('meet',), age=18)	# 给子进程对象添加一个age属性。
print(p.age) # 18

6. 僵尸进程与孤儿进程

6.1 僵尸进程

实际中,主进程只有等待子进程结束后,主进程才结束。

基于Unix环境(linux,macOS):

主进程时刻监测子进程的运行状态,当子进程结束后,一段时间内,才会将子进程回收。

为什么不马上回收?

  1. 主进程与子进程是异步关系,主进程无法马上会获取子进程是什么时候结束;
  2. 如果子进程结束之后马上在内存中释放资源,主进程就没有办法监测子进程的状态。

Unix针对上面的问题,提供了一种机制:

所有的子进程结束后,立马释放掉文件的操作链接、内存等的大部分数据,但是会保留一些内容:进程号、结束时间、运行状态,等待子进程监测、回收。

僵尸进程:子进程在结束后,主进程并没有调用wait或waitpid获取子进程的状态信息,子进程仍然保留了一些描述内容,这种进程被称为僵尸进程。

​ 危害:如果父进程不对僵尸进程进行回收(wait/waitpid),产生大量的僵尸进程,这样会占用内存,占用进程的pid号。

6.2 孤儿进程

父进程由于某种原因结束,但子进程还在运行中,则称这些子进程为孤儿进程。

回收机制:Unix中孤儿进程会被 init 进程回收,init 变成父进程。

僵尸进程解决方法

​ 直接杀死父进程。将所有僵尸进程变成孤儿进程,由 init进程回收。

7. 守护进程

# 子进程守护着主进程,只要主进程结束,子进程也跟着结束。

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=('meet',)) # 创建一个进程对象
p.daemon = True # 放在start前,否则会报错。
p.start()
time.sleep(1)
print("===主进程")
"""
meet is running
===主进程
"""

python 33 多进程(一)的更多相关文章

  1. 『Python』多进程处理

    尝试学习python的多进程模组,对比多线程,大概的区别在: 1.多进程的处理速度更快 2.多进程的各个子进程之间交换数据很不方便 多进程调用方式 进程基本使用multicore() 进程池优化进程的 ...

  2. Python多线程多进程那些事儿看这篇就够了~~

    自己以前也写过多线程,发现都是零零碎碎,这篇写写详细点,填一下GIL和Python多线程多进程的坑~ 总结下GIL的坑和python多线程多进程分别应用场景(IO密集.计算密集)以及具体实现的代码模块 ...

  3. 【python】多进程锁multiprocess.Lock

    [python]多进程锁multiprocess.Lock 2013-09-13 13:48 11613人阅读 评论(2) 收藏 举报  分类: Python(38)  同步的方法基本与多线程相同. ...

  4. Python实现多进程

    Python可以实现多线程,但是因为Global Interpreter Lock (GIL),Python的多线程只能使用一个CPU内核,即一个时间只有一个线程在运行,多线程只是不同线程之间的切换, ...

  5. python 使用多进程实现并发编程/使用queue进行进程间数据交换

    import time import os import multiprocessing from multiprocessing import Queue, pool ""&qu ...

  6. Python多线程多进程

    一.线程&进程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程, ...

  7. python中多进程+协程的使用以及为什么要用它

    前面讲了为什么python里推荐用多进程而不是多线程,但是多进程也有其自己的限制:相比线程更加笨重.切换耗时更长,并且在python的多进程下,进程数量不推荐超过CPU核心数(一个进程只有一个GIL, ...

  8. Python的多进程

    这里不说其它,Python的多进程网上已经有很多了,可以尽情搜索.但是用多进程一般是采用对任务的方式,所以注意文件锁定.一般采用Pool是比较合适的.给个网友的小代码 from multiproces ...

  9. 进程,线程,以及Python的多进程实例

    什么是进程,什么是线程? 进程与线程是包含关系,进程包含了线程. 进程是系统资源分配的最小单元,线程是系统任务执行的最小单元. 打个比方,打开word,word这个程序是一个进程,里面的拼写检查,字数 ...

随机推荐

  1. Java 读写 excel 实战完全解析

    本文微信公众号「AndroidTraveler」首发. 背景 时值毕业季,很多毕业生初入职场. 因此,这边也写了一些新手相关的 Android 技术点. 比如上一篇的 Android 开发你需要了解的 ...

  2. Visual Studio 调试系列1 Debug 与 Release 模式

    系列目录     [已更新最新开发文章,点击查看详细] Debug 模式 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序. 在Debug模式下调试,可以在断点处看到 ...

  3. Cocos2d-x 3.x中自定义渲染功能

    1.第一种方法针对的是整个图层的渲染         重写visit()函数,并且在visit()函数中直接向CommandQueue添加CustomCommand,设置好回调函数.          ...

  4. zabbix3.4汉化

    1.管理员用户登入zabbix页面,更改语言为Chinese(zh_CN),点击Update 2.解决zabbix页面中文乱码 2.1在windows的C:\Windows\Fonts找到字体文件si ...

  5. 2019牛客暑期多校训练营(第四场)K.number

    >传送门< 题意:给你一个字符串s,求出其中能整除300的子串个数(子串要求是连续的,允许前面有0) 思路: >动态规划 记f[i][j]为右端点满足mod 300 = j的子串个数 ...

  6. 灵活使用Maven Profile

    项目中一直应用Maven的profile特性解决不同环境的部署问题.最近在尝试解决本地调试环境的时候碰到一些问题,顺便仔细研究了一下.因为项目仍然在用普通SpringMVC架构,没有切换到Spring ...

  7. $.ajax()在IE9下的兼容性问题

    最近在主导一个项目,遇到了一点问题,跟大家分享一下. 最终bug解决方案的链接地址:http://stackoverflow.com/questions/5241088/jquery-call-to- ...

  8. istio使用教程

    kubernetes各版本离线安装包 安装 安装k8s 强势插播广告 三步安装,不多说 安装helm, 推荐生产环境用helm安装,可以调参 release地址 如我使用的2.9.1版本 yum in ...

  9. 2019.7 佳木斯培训A层

    day1题目及题解 day2题目及题解 day3题目及题解 day4题目及题解 day5题目及题解

  10. 【有容云案例系列】基于Jenkins和Kubernetes的CI工作流

    嘉宾介绍 黄文俊 有容云资深系统架构师 主要负责容器云平台产品架构及设计. 8年工作经验, 有着企业级存储, 云计算解决方案相关理解. 关注于微服务设计思考, 开发流程优化, docker及kuber ...