进程
1. 什么是进程
一个正在运行的程序或者软件就是一个进程,它是操作系统进行资源分配的基本单位,也就是说每启动一个进程,操作系统都会给其分配一定的运行资源(内存资源)保证进程的运行。
1.1 进程的使用
首先进程包的导入
import multiprocessing
多任务进程的实现
# 导入进程包
import multiprocessing
import time
# 任务函数
def task1():
for i in range(10):
print('a--', i+1)
time.sleep(1)
def task2():
for i in range(10):
print('b--', i+1)
time.sleep(1)
if __name__ == '__main__':
p1 = multiprocessing.Process(target=task1)
p2 = multiprocessing.Process(target=task2)
# 注意不是task()括号,没有括号,加了括号就是执行的结果了
# p2 = multiprocessing.Process(target=task2())
# 启动进程
p1.start()
p2.start()
参数的说明:
Process([group [, target [, name [, args [, kwargs]]]]])
group:指定进程组,目前只能使用None
target:执行的目标任务名
name:进程名字
args:以元组方式给执行任务传参
kwargs:以字典方式给执行任务传参
Process创建的实例对象的常用方法:
start():启动子进程实例(创建子进程)
join():等待子进程执行结束
terminate():不管任务是否完成,立即终止子进程
Process创建的实例对象的常用属性:
name:当前进程的别名,默认为Process-N,N为从1开始递增的整数
1.2 获取进程的id,os.getpid()
# 导包
import multiprocessing
import os
# 创建任务
def task1():
print(f'任务1的pid:{os.getpid()},父进程的pid:{os.getppid()}')
def task2():
print(f'任务2的pid:{os.getpid()},父进程的pid:{os.getppid()}')
# 创建子进程
if __name__ == '__main__':
print(f'主进程的pid:{os.getpid()},父进程的pid:{os.getppid()}')
# 创建子进程
# p1 = multiprocessing.Process(target=task1)
# p2 = multiprocessing.Process(target=task2)
# < Process name = 'Process-1'parent = 6308 initial >
# < Process name = 'Process-2' parent = 6308 initial >
# 给定进程名字
p1 = multiprocessing.Process(target=task1, name='p1')
p2 = multiprocessing.Process(target=task2, name='p2')
print(p1)
print(p2)
# 启动
p1.start()
p2.start()
print(p1)
print(p2)
1.3 获取进程的对象multiprocessing.current_process()
# 导包
import multiprocessing
import os
# 创建任务
def task1():
mp_task1 = multiprocessing.current_process()
print(mp_task1)
print(mp_task1.name)
print(f'任务1的pid:{os.getpid()},父进程的pid:{os.getppid()}')
def task2():
mp_task2 = multiprocessing.current_process()
print(mp_task2)
print(mp_task2.name)
print(f'任务2的pid:{os.getpid()},父进程的pid:{os.getppid()}')
# 创建子进程
if __name__ == '__main__':
print(f'主进程的pid:{os.getpid()},父进程的pid:{os.getppid()}')
mp = multiprocessing.current_process()
print(mp)
print(mp.name)
# 给定进程名字
p1 = multiprocessing.Process(target=task1, name='p1')
p2 = multiprocessing.Process(target=task2, name='p2')
print(p1)
print(p2)
# 启动
p1.start()
p2.start()
print(p1)
print(p2)
1.4 参数的使用args kwargs
import multiprocessing
import time
def task1(count):
for i in range(count):
print('task1--', i+1)
time.sleep(0.5)
def task2(content, count):
for i in range(count):
print(content, i+1)
time.sleep(0.5)
if __name__ == '__main__':
# args的传参方式是元组,是只有一个的话,需要逗号
# p1 = multiprocessing.Process(target=task1,args=(5,))
# p2 = multiprocessing.Process(target=task2,args=('hello',4))
# kwargs的传参新式字典
p1 = multiprocessing.Process(target=task1, kwargs={'count': 5})
p2 = multiprocessing.Process(target=task2, kwargs={'count': 5, 'content': 'python'})
p1.start()
p2.start()
1.5 进程之间不共享全局变量
创建子进程会对主进程资源进行拷贝,也就是说子进程是主进程的一个副本,好比是一对双胞胎,之所以进程之间不共享全局变量,是因为操作的不是同一个进程里面的全局变量,只不过不同进程里面的全局变量名字相同而已。
import multiprocessing
import time
g_list = []
def add_data():
for i in range(5):
g_list.append(i)
print('add:', i)
time.sleep(0.5)
print('add_sucess', g_list)
def read_data():
print('read_data', g_list)
if __name__ == '__main__':
add_data_p1 = multiprocessing.Process(target=add_data)
read_data_p2 = multiprocessing.Process(target=read_data)
add_data_p1.start()
# p1执行昂成才会执行p2
add_data_p1.join()
read_data_p2.start()
print('main', g_list)
1.6 主进程会等子进程结束在结束
import multiprocessing
import time
# 定义进程所需要执行的任务
def task():
for i in range(10):
print("任务执行中...")
time.sleep(0.2)
if __name__ == '__main__':
# 创建子进程
sub_process = multiprocessing.Process(target=task)
sub_process.start()
# 主进程延时0.5秒钟
time.sleep(0.5)
print("over")
exit()
# 总结: 主进程会等待所有的子进程执行完成以后程序再退出
1.7 守护主进程
守护主进程就是主进程退出子进程销毁不再执行
方式一:
p1.daemon = True
方式二:
p1.terminate()
案例:
import multiprocessing
import time
def task():
for i in range(5):
print('i==:', i)
time.sleep(0.5)
if __name__ == '__main__':
p1 = multiprocessing.Process(target=task)
# 方式一 在start之前
p1.daemon = True
p1.start()
time.sleep(0.5)
# 方式二 在start之后
# p1.terminate()
print('main is over')