多任务的介绍
1、多任务的执行
并发:在一段时间内交替去执行任务。
并行:对于多核cpu处理多任务,操作系统会给cpu的每个内核安排一个执行的软件,多个内核是真正的一起执行软件。这里需要注意多核cpu是并行的执行多任务,始终有多个软件一起执行。
任务数大于cpu的核数表示并发的去执行多任务
任务数小于等于cpu核数表示并行的去执行多任务
2、小结
进程
1、进程的介绍
在Python程序中,想要实现多任务可以使用进程来完成,进程是实现多任务的一种方式。
2、进程的概念
一个正在进行的程序或者软件就是一个进程,它是操作系统进行资源分配的基本单位,也就是说每启动一个进程,操作系统都会给其分配一定的运行资源(内存资源)保证进程的运行。
比如:现实生活中的公司可以理解成是一个进程,公司提供办公资源(电脑、办公桌椅等),真正干活的是员工,员工可以理解为线程。
注意:
一个程序运行至少有一个进程,一个进程默认有一个线程,进程里面可以创建多个线程,线程是依附子啊进程里面的, 没有进程就没有线程。
3、进程的作用
单进程效果图:
多进程效果图:
4、小结
多进程的使用
1、导入进程包
#导入进程包
import multiprocessing
2、Process进程类的说明
Proces([group[,targt[,name[,args[,kwargs]]]]])
Process创建的实例对象的常用方法:
Process创建的实例对象的常用属性:
name:当进程的别名,默认为Process- N,N为从1开始递增的整数
获取进程编号
1、获取进程编号的目的
获取进程编号的目的是验证主进程和子进程的关系,可以得知子进程是由哪个主进程创建出来的。
获取进程编号的两种操作:
2、获取当前进程编号
os.getpid()表示获取当前进程编号
代码演示:
import multiprocessing
import time
import os
# 跳舞任务
def dance():
# 获取当前进程的编号
print("dance", os.getpid())
# 获取当前进程
print("dance", multiprocessing.current_process())
for i in range(5):
print("跳舞中···")
time.sleep(0.2)
# 扩展:根据进程编号杀死指定进程
os.kill(os.getpid(), 9)
# 唱歌任务
def sing():
# 获取当前进程的编号
print("sing", os.getpid())
# 获取当前进程
print("sing", multiprocessing.current_process())
for i in range(5):
print("唱歌中···")
time.sleep(0.2)
if __name__ == '__main__':
# 获取当前进程号
print("main", os.getpid())
# 获取当前进程
print("main", multiprocessing.current_process())
# 创建跳舞的子进程
# group:表示进程组,目前只能使用None
# target:表示执行的目标任务名(函数名,方法名)
# name:进程名称,默认是Process -N N从1开始依次递增
dance_process = multiprocessing.Process(target=dance, name="myprocess1")
sing_process = multiprocessing.Process(target=sing)
# 启动子进程执行对应的任务
dance_process.start()
sing_process.start()
3、获取当前父进程编号
os.getppid()表示获取当前父进程编号
代码演示:
# -*- codeing = utf-8 -*-
# @Time : 2021/12/4 10:51 下午
# @Author : 李明辉
# @File : ithui_多进程.py
# @Software : PyCharm
import multiprocessing
import time
import os
# 跳舞任务
def dance():
# 获取当前进程的编号
print("dance", os.getpid())
# 获取当前进程
print("dance", multiprocessing.current_process())
# 获取当前进程对象,查看当前代码是由哪个进程执行的,multiprocessing.current_process()
print('main_process_id', os.getpid(), multiprocessing.current_process())
# 获取父进程的编号
print("dance", os.getppid())
for i in range(5):
print("跳舞中···")
time.sleep(0.2)
# 扩展:根据进程编号杀死指定进程
os.kill(os.getpid(), 9)
# 唱歌任务
def sing():
# 获取当前进程的编号
print("sing", os.getpid())
# 获取当前进程
print("sing", multiprocessing.current_process())
print('main_process_id', os.getpid(), multiprocessing.current_process())
# 获取父进程的编号
print("sing", os.getppid())
for i in range(5):
print("唱歌中···")
time.sleep(0.2)
if __name__ == '__main__':
# 获取当前进程号
print("main", os.getpid())
# 获取当前进程
print("main", multiprocessing.current_process())
# 创建跳舞的子进程
# group:表示进程组,目前只能使用None
# target:表示执行的目标任务名(函数名,方法名)
# name:进程名称,默认是Process -N N从1开始依次递增
dance_process = multiprocessing.Process(target=dance, name="myprocess1")
sing_process = multiprocessing.Process(target=sing)
# 启动子进程执行对应的任务
dance_process.start()
sing_process.start()
进程执行带有参数的任务的介绍
1、进程执行带有参数的任务的介绍
Process类执行任务传参数有两种方式:
2、args参数的使用
代码演示:
# -*- codeing = utf-8 -*-
# @Time : 2021/12/4 11:27 下午
# @Author : 李明辉
# @File : ithui_进程带有参数的任务.py
# @Software : PyCharm
import multiprocessing
import time
# 显示信息的任务
def show_info(name, age):
print(name, age)
# 创建子进程
# 1、以元组方式传参
sub_process = multiprocessing.Process(target=show_info, args=("李四", 20))
# 2、以字典方式传参
# sub_process = multiprocessing.Process(target=show_info, kwargs={"name":"李四", "age":20})
# 3、以元组和字典一起传参
# sub_process = multiprocessing.Process(target=show_info, args=("李四",), kwargs={"age":20})
# 启动进程
if __name__ == '__main__':
sub_process.start()
3、kwargs参数的使用
代码演示:
# -*- codeing = utf-8 -*-
# @Time : 2021/12/4 11:27 下午
# @Author : 李明辉
# @File : ithui_进程带有参数的任务.py
# @Software : PyCharm
import multiprocessing
import time
# 显示信息的任务
def show_info(name, age):
print(name, age)
# 创建子进程
# 1、以元组方式传参
# sub_process = multiprocessing.Process(target=show_info, args=("李四", 20))
# 2、以字典方式传参
sub_process = multiprocessing.Process(target=show_info, kwargs={"name":"李四", "age":20})
# 3、以元组和字典一起传参
# sub_process = multiprocessing.Process(target=show_info, args=("李四",), kwargs={"age":20})
# 启动进程
if __name__ == '__main__':
sub_process.start()
4、args和kwargs一起使用
代码演示:
# -*- codeing = utf-8 -*-
# @Time : 2021/12/4 11:27 下午
# @Author : 李明辉
# @File : ithui_进程带有参数的任务.py
# @Software : PyCharm
import multiprocessing
import time
# 显示信息的任务
def show_info(name, age):
print(name, age)
# 创建子进程
# 1、以元组方式传参
# sub_process = multiprocessing.Process(target=show_info, args=("李四", 20))
# 2、以字典方式传参
# sub_process = multiprocessing.Process(target=show_info, kwargs={"name":"李四", "age":20})
# 3、以元组和字典一起传参
sub_process = multiprocessing.Process(target=show_info, args=("李四",), kwargs={"age":20})
# 启动进程
if __name__ == '__main__':
sub_process.start()
进程的注意点
1、进程的注意点介绍
2、进程之间不共享全局变量
代码演示:
# -*- codeing = utf-8 -*-
# @Time : 2021/12/6 10:09 下午
# @Author : 李明辉
# @File : ithui_进程之间不共享全局变量.py
# @Software : PyCharm
import multiprocessing
import time
# 定义全局变量
g_list = list()
# 添加数据的任务
def add_data():
for i in range(3):
g_list.append(i)
print("add:", i)
time.sleep(0.2)
print("添加完成", g_list)
# 读取数据的任务
def read_data():
print("read:", g_list)
# 添加数据的子进程
add_process = multiprocessing.Process(target=add_data)
# 读取数据的子进程
read_process = multiprocessing.Process(target=read_data)
if __name__ == '__main__':
# 启动进程执行对应的任务
add_process.start()
# 当前进程(主进程)等待添加数据的进程执行完成以后代码再继续乡下执行
add_process.join()
read_process.start()
执行结果:
创建子进程只是对主进程资源进行拷贝,子进程其实就是主进程的副本。
3、主进程会等待所有子进程执行结束后再结束
代码演示:
# -*- codeing = utf-8 -*-
# @Time : 2021/12/6 10:57 下午
# @Author : 李明辉
# @File : ithui_主进程会等待所有子进程执行结束再结束.py
# @Software : PyCharm
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.daemon = True
sub_process.start()
# 主进程延时0.5秒钟
time.sleep(0.5)
print("over")
END