多进程

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. HTML--表格与表单(练习做注册页面)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. Git学习(二):Git的初步使用

    一.Git的最小配置 1.使用如下命令创建Git的用户名和邮箱,如下所示: $git config --global user.name 'your_name' $git config --globa ...

  3. [P2216] [HAOI2007]理想的正方形 「单调队列」

    思路:用单调队列分别维护行与列. 具体实现方法:是先用单调队列对每一行的值维护,并将a[][]每个区间的最大值,最小值分别存在X[][]和x[][]中. 那么X[][]与x[][]所存储的分别是1×n ...

  4. jsp的简介(2)

    JSP(JavaServer Pages )是什么? JavaServer Pages(JSP)是一种支持动态内容开发的网页技术它可以帮助开发人员通过利用特殊的JSP标签,其中大部分以<%开始并 ...

  5. SparkStreaming对接rabbitMQ

    /** * SparkStreaming对接rabbitmq java代码 */public class SparkConsumerRabbit { public static void main(S ...

  6. 第三章、Go-内建容器

    3.1.数组 (1)数组的定义 package main import ( "fmt" ) func main() { //用var定义数组可以不用赋初值 var arr1 [5] ...

  7. 五、Python基础(2)

    五,Python基础(2) 1.数据类型基础 (一)什么是数据类型? 用于区分变量值的不同类型. (二)为何对数据分类? 针对不同状态就应该用不同类型的数据去标识. (三)数据类型分类 1.数字类型 ...

  8. 从无到满意offer,你需要知道的那些事

    本文首发于微信公众号:[坂本先生] 原文地址:从无到满意offer,你需要知道的那些事 1.求职软件/网站汇总 软件 评价 推荐指数 拉钩网 手机端产品设计的比较好,当时在上面找到了很多的面试机会 5 ...

  9. Unity实现放大缩小以及相机位置平移实现拖拽效果

    放大缩小功能是游戏开发中用到的功能,今天就来讲一下Unity中放大缩小怎么实现. 1.IDragHandler, IBeginDragHandler, IEndDragHandler这三个接口是Uni ...

  10. 201312-2ISBN号码

    问题描述 每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字.1位识别码和3位分隔符,其规定格式如“x-xxx-xxxxx-x”,其中符号“-”是分隔符(键盘上的减号),最后一位 ...