一个运行的程序,会包括至少一个进程,每一个进程中包括至少一个线程
每个cpu在单位时间只能运行一个进程
cpu在进程间的切换速度飞快,宏观表现为多个进程同时运行,但微观上仍有先后顺序
并发:看似一起运行,宏观上的感念
并行:真正一起运行,微观的概念
每个运行的进程,都有一个唯一的pid(类似身份证)
父进程的pid,称为ppid(parent pid:爸爸的身份证)
from multiprocessing import Process
import time # 用于延时
# 定义子线程运行的目标函数
def func():
for i in range(3):
print(i)
# main:表示主进程
if __name__ == '__main__':
# 实例化process进程对象,目标执行func函数
process = Process(target=func)
# 运行processs进程
process.start()
# 主进程也运行func函数
func()
args:根据元组中的索引对应函数接受的参数
kwargs:根据字典中的key对应函数接受的参数
from multiprocessing import Process
# 目标方法,接受两个参数
def func(param1,param2):
print(param1,param2)
if __name__ == '__main__':
# 根据索引对应传入参数
process1 = Process(target=func,args=('value1','value2'))
process1.start()
# 根据字典的键对应传入参数
process2 = Process(target=func,kwargs={'param1':'value1','param2':'value2'})
process2.start()
命令 | 说明 |
---|---|
name | 设置或获取进程的别名 |
pid | 获取进程的pid |
start() | 运行 |
is_alive() | 判断进程是否正在运行 |
join(timeout) | 子进程运行完,或已堵塞timeout秒后,放行主进程 |
terminate() | 停止子进程 |
例如:
from multiprocessing import Process
import time # 用于延时
# 子进程运行的目标方法
def func():
for i in range(10000):
print(i)
time.sleep(1)
if __name__ == '__main__':
process = Process(
target=func,
name='子进程1', # 1.name 为进程起别名
)
# 2.start 运行进程
process.start()
# 3.pid 得到子进程的pid
print('子进程的pid=',process.pid)
# 4.is_alive() 判断进程是否正在运行
print(process.is_alive())
# 5.join() 堵塞主进程
process.join(timeout=2)
# 6.terminate() 停止子进程
process.terminate()
命令 | 说明 |
---|---|
os.getpid() | 得到当前进程的pid |
os.getppid() | 得到当前进程的父进程的pid |
process.pid | 得到process进程的pid |
from multiprocessing import Process
import os
def func():
print('子进程的pid=',os.getpid())
print('子进程的ppid=',os.getppid())
if __name__ == '__main__':
process = Process(target=func)
process.start()
print('process的pid=',process.pid)
print('主进程的pid=',os.getppid())
步骤:
例如:
from multiprocessing import Process
# 1.定义类对象,继承Process
class MyProcess(Process):
def __init__(self,param):
# 2.1 调用父类的init方法
Process.__init__(self)
# 2.2 处理接受参数
self.param = param
# 3. 定义run方法(相当于进程执行的目标方法)
def run(self):
print(self.param)
if __name__ == '__main__':
# 4.1 实例化类对象
myProcess = MyProcess('value')
myProcess.start()
注意:
注意:进程之间不能共享全局变量,所以Global关键字不能作为进程通信的桥梁
进程通信的方法:
from multiprocessing import Process,Queue # 1.导入进程通信队列
# 2.进程目标函数需要接受队列
def func(q):
while True:
print(q.get())
if __name__ == '__main__':
# 3.实例化进程通信队列
queue = Queue()
# 4.传递队列
Process(target=func,args=(queue,)).start()
# 5.队列通信例子:
import time
for i in range(5):
queue.put(i)
time.sleep(1)
1.queue = Queue(maxsize=-1):
2.queue.get(block=True,timeout=None)
3.queue.get_nowait()
4.queue.put(obj,block=True,timeout=None)
5.queue.put_nowait(obj)
6.queue.qsize()
7.queue.empty()
8.queue.full()
生命周期:
Process进程执行的流程:
如果某个程序需要频繁的通过进程的方式运行多种目标函数,如果使用Process,频繁的创建和销毁进程会浪费大量的资源,所有就有了池的概念
Pool进程池
注:如果进程池中没有空闲进程,那么目标函数无法执行
优势:省去了频繁创建进程和销毁进程的资源
步骤:
例如:
from multiprocessing import Pool
import time
def func(param):
for i in range(3):
print(param)
time.sleep(1)
if __name__ == '__main__':
# 1.实例化进程池(池中有两个进程)
pool = Pool(2)
# 2.告诉进程池要执行的目标函数
for i in range(10):
pool.apply_async(
func=func, # 指定目标函数
args=(i,) # 传递参数
)
# 3.关闭进程池
pool.close()
# 4.堵塞主进程
pool.join()
类似Process进程通信,唯一不同的地方是导包:
from multiprocessing import Manager
queue = Manager().Queue()
Pool通信队列Queue的常用方法与上面Process中列举的相同
生命周期:
这也是为什么需要使用pool.join()的原因
联系方式:[email protected]