多进程

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. Cesium 学习(三)各种资源链接

    1.前言 前面已经介绍如何获得以及安装部署Cesium,接下来分享下学习资源链接,其中访问最多的是官网以及超图.火星的demo网站. 2.官网地址及介绍 官网:https://cesiumjs.org ...

  2. 小白学python-day05-作业(购物车程序)

    购物车需求: 开始输入工资,然后出现购买商品的相关信息,输入编号进行购买 价格>工资提示余额不足,价格<工资提示 成功加入购物车,并且显示余额 然后将购买环节进行循环,直到用户退出购买 然 ...

  3. php laravel5.6引入geetest 行为验证

    php laravel5.6引入geetest 行为验证 使用必要性 网站和APP,在所有可能被机器行为攻击的场景,例如但不限于注册.登录.短信接口.查询接口.营销活动.发帖评论等等,都可以部署使用「 ...

  4. golang从context源码领悟接口的设计

    注:写帖子时go的版本是1.12.7 go语言中实现一个interface不用像其他语言一样需要显示的声明实现接口.go语言只要实现了某interface的方法就可以做类型转换.go语言没有继承的概念 ...

  5. IIS身份验证和文件操作权限(一、身份验证配置)

    最近有一个项目服务器需要升级,主要是Web项目.因为以前是只写代码,不管发布.所以在环境构筑方面就出现自己的知识盲点.盲点一:IIS的身份验证的作用盲点二:IIS的身份验证和文件操作权限的关系(重点) ...

  6. VS Code 安装 LeetCode 插件

    练习算法绕不开的一个网站就是力扣,很多小伙伴为了拿到大厂 offer,刷题都刷到吐了. 然而如果直接在 LeetCode 上写代码,那是很痛苦的一件事,那就相当于用 txt 写代码一样,没有 IDE ...

  7. MyBatis 文档 完整版

    框架技术 1.框架技术 01.是一个应用程序的半成品 02.提供可重用的公共结构 03.按一定规则组织的一组组件 2.分析优势 01.不用再考虑公共问题 02.专心的业务实现上 03.结构统一,易于学 ...

  8. hdoj 1753 (Java)

    刚刚开始用Java,代码难免不够简洁. import java.math.BigDecimal; import java.util.Scanner; public class Main { publi ...

  9. Codeforces Round #192 (Div. 2) (330B) B.Road Construction

    题意: 要在N个城市之间修建道路,使得任意两个城市都可以到达,而且不超过两条路,还有,有些城市之间是不能修建道路的. 思路: 要将N个城市全部相连,刚开始以为是最小生成树的问题,其实就是一道简单的题目 ...

  10. php 获取未来七天的日期和星期

    php获取未来七天的日期和星期代码     for($i=4;$i<8;$i++){       $dateArray[$i]=date('Y-m-d',strtotime(date('Y-m- ...