multiprocess.Process模块

【3.0】多进程操作
【一】multiprocessing模块介绍
python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程。
Python提供了multiprocessing。
multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似。
multiprocessing模块的功能众多:
支持子进程、通信和共享数据、执行不同形式的同步
提供了Process、Queue、Pipe、Lock等组件。
需要再次强调的一点是:
与线程不同,进程没有任何共享状
进程修改的数据,改动仅限于该进程内。
【二】Process类的介绍
【1】创建进程的类
语法
由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)
强调:
需要使用关键字的方式来指定参数
args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号
【2】参数介绍
group参数未使用,值始终为None
target表示调用对象,即子进程要执行的任务
args表示调用对象的位置参数元组,args=(1,2,'ly',)
kwargs表示调用对象的字典,kwargs={'name':'ly','age':18}
name为子进程的名称
【3】方法介绍
p.start():
启动进程,并调用该子进程中的p.run()
p.run():
进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法
p.terminate():
强制终止进程p,不会进行任何清理操作
如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。
如果p还保存了一个锁那么也将不会被释放,进而导致死锁
p.is_alive():
如果p仍然运行,返回True
p.join([timeout]):
主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。
timeout是可选的超时时间
需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程
【4】属性介绍
p.daemon:
默认值为False
如果设为True,代表p为后台运行的守护进程
当p的父进程终止时,p也随之终止
并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
p.name:
进程的名称
p.pid:
进程的pid
p.exitcode:
进程在运行时为None、如果为–N,表示被信号N结束(了解即可)
p.authkey:
进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。
这个键的用途是为涉及网络连接的底层进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功(了解即可)
【三】Process类的使用
【1】特别提醒
注意:在windows中Process()必须放到 if name == 'main':下
详细解释
【2】创建并开启子进程的两种方式
(1)方法一:直接使用Process方法
(2)方法二:继承Process类
(3)小结
创建进程就是在内存中申请一块内存空间将需要运行的代码丢进去
一个进程对应在内存中就是一块独立的空间
多个进程对应在内存中就是多块独立的内存空间
进程与进程之间数据默认情况下是无法直接交互的,如果想交互可以借助第三方工具或模块
【3】进程之间的内存空间是隔离的
每一个子进程之间的数据是相互隔离的
在执行子进程代码时,只修改自己子进程内的数据,不会影响到其他的子进程
【4】socket通信变成并发的形式
(1)server端
(2)多个client端
这么实现有没有问题???
每来一个客户端,都在服务端开启一个进程,如果并发来一个万个客户端,要开启一万个进程吗,你自己尝试着在你自己的机器上开启一万个,10万个进程试一试。
解决方法:进程池
【5】Process对象的join方法
将并行转为串行
join:主进程等,等待子进程结束
(1)非join方法 -- 并行
(2)join方法 -- 串行
(3)join方法 -- 并行
【四】Process对象的其他方法或属性(了解)
【1】查看当前进程的进程号
(1)引入
(1)什么是进程号
一台计算机上面运行着很多进程,那么计算机是如何区分并管理这些进程服务端呢?
计算机会给每一个运行的进程分配一个PID号
(2)如何查看进程号?
Windows系统
CMD 命令行 tasklist 即可查看
Mac系统
终端运行 ps aux 即可查看
(3)如何根据指定进程号查看进程
Mac系统
终端运行 ps aux|grep PID 即可查看
Windows系统
CMD 命令行 tasklist |findstr PID 即可查看
(2)查看当前进程的进程号current_process().pid 方法
(3)查看当前进程的进程号os.getpid() 方法
(4)查看当前进程的父进程的进程号os.getppid() 方法
Python
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from multiprocessing import Process
import os
import time

def task():
# 查看当前进程的 进程(PID) 号
print(f'当前程序:>>>>{os.getpid()} 正在运行')
# 查看当前进程的 父进程(PID) 号
print(f'当前程序的父进程:>>>>{os.getppid()} 正在运行')
time.sleep(2)

if name == 'main':
p = Process(target=task)
p.start()

print(f'这是主程序:>>>{os.getpid()}')
print(f'这是主程序的父进程:>>>{os.getppid()}')

# 这是主程序:>>>22236
# 这是主程序的父进程:>>>17720
# 当前程序:>>>>3756 正在运行
# 当前程序的父进程:>>>>22236 正在运行

【2】杀死当前进程p.terminate()
告诉操作系统帮我去杀死当前进程
但是需要一定的时间。
代码的运行速度极快
【3】判断当前进程是否存活p.is_alive()
Python
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from multiprocessing import Process
import os
import time

def task():
# 查看当前进程的 进程(PID) 号
print(f'当前程序:>>>>{os.getpid()} 正在运行')
print(f'当前程序的父进程:>>>>{os.getppid()} 正在运行')

time.sleep(2)

if name == 'main':
p = Process(target=task)
p.start()

# 杀死当前进程 - 需要给操作系统一点缓冲时间
p.terminate()
time.sleep(0.2)
# 判断当前进程是否存活
print(p.is_alive())

print(f'这是主程序:>>>{os.getpid()}')
print(f'这是主程序的父进程:>>>{os.getppid()}')

# 主进程正常
# 调用程序中的子进程被杀死
# False
# 这是主程序:>>>16796
# 这是主程序的父进程:>>>17720

一般默认会将
存储布尔值的变量名
返回的结果是布尔值的方法名
起成is_ 开头的变量名

posted @   zenopan  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示