多进程编程
1、介绍
**多任务定义:**同一时间执行多个任务
**多任务目的:**充分利用CPU资源,提高程序运行效率
表现方式:
- **并行:**同时执行多个任务
- **并发:**交替完成多个任务
进程(资源分配和调度的基本单位):正在运行的程序
2、多进程完成多任务
(1) 导入进程包
import multiprocessing
(2) 创建子进程并制定执行的任务
sub_process = multiprocessing.Process(target=任务名)
(3) 启动进程执行任务
sub_process.start()
代码:
def sing():
for i in range(3):
print('唱歌···')
time.sleep(1)
def dance():
for i in range(3):
print('跳舞···')
time.sleep(1)
if __name__ == '__main__':
# 使用进程类创建进程对象
# target:指定过程执行的函数名
sing_process = multiprocessing.Process(target=sing)
dance_process = multiprocessing.Process(target=dance)
sing_process.start()
dance_process.start()
3、进程执行中带有参数的任务
参数名 | 说明 |
---|---|
args | 以元组的方式给执行任务传参; 元组顺序必须与参数顺序一致,否则报错;一个参数时,不要忘记后面的逗号 |
kwargs | 以字典的方式给执行任务传参;按照键的名字进行传参,与顺序无关,但必须与函数的参数名一致 |
1)args
参数的使用:sing_process = multiprocessing.Process(target=sing, args=(3,))
2)kwargs
参数的使用:sing_process = multiprocessing.Process(target=sing, kwargs={'num':3})
4、获取进程的编号
为有效管理进程,对进程编号进行管理。
1)获取当前正在使用进程的编号:os.getpid()
2)获取当前进程父进程的编号:os.getppid()
5、进程的注意点
1)主进程会等待所有子进程结束后在结束,除非设置守护主进程
2)设置守护主进程,主进程结束子进程进程自动销毁,不在执行子进程代码
设置方式:sub_process.daemon =True
6、视频文件夹高并发copy器
import os
import multiprocessing
def copy_file(file_name, source_dir, destiny_dir):
# 1、拼接文件夹,构成源文件路径和目标文件
source_path = source_dir + '/' + file_name
destiny_path = destiny_dir + '/' + file_name
with open(source_path, 'rb') as fr:
fw = open(destiny_path, 'wb')
lines = fr.read()
fw.write(lines)
fw.close()
if __name__ == '__main__':
# 1、定义源文件夹和目标文件夹
source_dir = r'D:\学习资料\Python视频\进阶\中级\视频-2小时玩转python多线程编程\让程序“三头六臂”--多任务编程入门'
destiny_dir = 'E:/video'
# 2、创建目标文件夹
try:
os.mkdir(destiny_dir)
except:
print('文件夹已经存在!')
# 3、读取源文件夹的文件列表
file_list = os.listdir(source_dir)
# 4、遍历文件列表实现拷贝
for file_name in file_list:
# 5、使用多进程实现多任务拷贝
copy_file_process = multiprocessing.Process(target=copy_file, args=(file_name, source_dir, destiny_dir))
copy_file_process.start()
多线程编程
1、线程的介绍
多任务的另一种实现方式,线程是程序执行的最小单位,进程负责分配资源,利用这些资源执行程序的是线程,进程是线程的容器,一个进程中最少有一个线程负责执行程序,同时线程自己不拥有系统资源,只需要一点在运行中必不可少的资源,但他可与同属于一个进程的其他线程共享进程所拥有的全部资源。
2、多线程完成多任务
(1) 导入进程包
import threading
(2) 创建子进程并制定执行的任务
sub_thread = threaing.Thread(target=任务名)
(3) 启动进程执行任务
sub_thead.start()
代码:
import threading
import time
def sing():
for i in range(3):
print('唱歌···')
time.sleep(1)
def dance():
for i in range(3):
print('跳舞···')
time.sleep(1)
if __name__ == '__main__':
# 使用线程类创建进程对象
# target:指定过程执行的函数名
sing_thread = threading.Thread(target=sing)
dance_thread = threading.Thread(target=dance)
# 启动进程
sing_thread.start()
dance_thread.start()
3、线程执行中带有参数的任务
参数名 | 说明 |
---|---|
args | 以元组的方式给执行任务传参; 元组顺序必须与参数顺序一致,否则报错;一个参数时,不要忘记后面的逗号 |
kwargs | 以字典的方式给执行任务传参;按照键的名字进行传参,与顺序无关,但必须与函数的参数名一致 |
1)args
参数的使用:sing_thread = threading.Thread(target=sing, args=(3,))
2)kwargs
参数的使用:sing_thread = threading.Thread(target=sing, kwargs={'num':3})
4、主线程与子线程的结束顺序
1)主线程会等待所有子线程结束后在结束,除非设置守护主线程
2)设置守护主线程,主线程结束子线程,子线程自动销毁,不在执行子线程代码
设置方式:
- 创建主线程是将
daemon=True
当做参数传入
sing_thread = threading.Thread(target=sing, daemon=True)
- 使用线程对象里面的
setDaemon(True)
,需写在在线程启动之前
sing_thread = multiprocessing.Process(target=sing)
sing_threading.setDaemon(True)
5、线程间的执行顺序
1)线程之间的执行时***无序的***;由CPU调度;
2)获取当前线程信息,通过**current_thread
方法**获取线程对象,通过current_thread
对象知道线程的相关信息;
current_thread = threading.current_thread()
6、进程与线程的区别
1)关系
- 线程是依附于进程,没有进程就没有线程
- 一个进程最少拥有一条线程,进程可以有多个线程
2)区别:
- 进程比线程开销大
- 进程是系统资源分配的基本单位,线程是CPU调度的基本单位
- 线程不能独立执行,必须依附于进程
3)优缺点:
- 进程:可以使用多核;资源开销大
- 线程:节省资源;但是不能使用多核