进程基础
进程是资源分配的最小单位,也是线程的容器。一个进程中包含多个线程。运行的程序及所调用的资源是进程。
进程的状态
使用进程
继承multiprocessing模块中的multiprocessing.Process()
类来创建一个模块,使用target=
指定要执行的函数,使用args=
或kwargs=
指定参数,使用group=
指定进程组,name=
指定进程名。最常用的就是target和args。【大体与线程相同】
# 导入模块
import multiprocessing
import time
# 定义函数
def sing():
for i in range(5):
print("singing...")
time.sleep(0.5)
def dance():
for i in range(5):
print("dancing...")
time.sleep(0.5)
if __name__ == "__main__":
# 创建进程对象
sing_pro_obj = multiprocessing.Process(target=sing)
sing_pro_obj.start()
dance()
获取进程名称/ID
- 获取当前进程名称
.current_process()
,他会给出进程名和父进程
这是主进程:<_MainProcess name='MainProcess' parent=None started>
。
这是某个name='Process-1'
的子进程:<Process name='Process-1' parent=11447 started>
。 - 使用
.current_process().pid
或os.getpid()
来得到进程的ID - 使用
os.getppid
获取进程的父ID。只有子进程才有父ID
杀死进程
- 在终端中使用
kill -9 进程ID
(可能会留下一些不完整的文件或状态)来强制杀死进程。 - 在终端中使用
kill -15 进程ID
(可能会阻塞)来使进程释放相应资源,然后再停止。- 应先使用
kill -15
,如无法杀死进程,再使用kill -9
。
- 应先使用
多进程中的参数传递
1.创建进程时使用元组传递
multiprocessing.Process(target=函数名,args=(参数1,参数2... ...))
注意:使用元组传参,参数顺序要一致!
2.创建进程时使用字典传递
multiprocessing.Process(target=函数名,kwargs={形参1=实参1,形参2=实参2... ...})
3.创建进程时混合使用元组和字典传递
multiprocessing.Process(target=函数名,args=(参数1,参数2... ...),kwargs={形参1=实参1,形参2=实参2... ...})
注意:使用字典传参,形参名一定要一致!
进程之间不共享全局变量!
子进程会复制主进程的资源,再在内部进行运行。
守护进程
设置.daemon = True
设置子进程守护主进程。
终止线程
使用.terminate()
强制终止进程
线程与进程
线程运行所需要的资源由进程提供,进程可以有多个线程。
多进程 | 多线程 | |
---|---|---|
数据共享、同步 | 数据是分开的,共享复杂,需要用IPC;同步简单 | IPC;同步简单 多线程共享进程数据,共享简单;同步复杂 |
内存、CPU | 占用内存多,切换复杂,CPU利用率低 | 占用内存少,切换简单,CPU利用率高 |
创建销毁、切换 | 创建销毁、切换复杂,速度慢 | 创建销毁、切换简单,速度快 |
编程调试 | 编程简单,调试简单 | 编程复杂,调试复杂 |
可靠性 | 进程间不会相互影响 | 一个线程挂掉将导致整个进程挂掉 |
分布式 | 适应于多核、多机分布 ;如果一台机器不够,扩展到多台机器比较简单 | 适应于多核分布 |
通常,线程和进程都是结合使用的。
进程池[默认守护主进程]
用于创建、管理、维护大量进程。
进程池可以选择同步或异步工作。
继承multiprocessing.Pool()
来创建一个进程。使用target=
指定要执行的函数,使用args=
或kwargs=
指定参数。
-
使用
apply()
以同步方式执行任务。 -
使用
apply_async(func,args,kwds)
来使用异步方式调用func。 需要.close()
来使进程池不再接受新的任务,同时主进程也不再等待进程池执行结束。 使用.jion()
使主进程等待进程池结束再退出。import time import multiprocessing def func(): print("...",multiprocessing.current_process()) time.sleep(1) if __name__ =="__main__": pool = multiprocessing.Pool(3) for i in range(10): pool.apply_async(func) pool.close() pool.join()