目录
一、必备知识
1、需掌握python基础语法、python文件操作、python模块应用
2、开发工具:pycharm、python3.6及以上版本
3、学习内容:进程、线程、多任务应用
二、多任务
1、概念
2、多任务的两种表现形式
三、进程
1、进程的概念
2、进程的创建
3、多进程完成多任务
4、进程执行带有参数的任务
5、获取进程编号
6、进程注意事项
7、案例----进程实现文件夹拷贝
四、线程
1、线程概念
2、线程创建步骤
3、多线程实现多任务
4、线程执行带有参数的任务
5、主线程和子线程的结束顺序
6、线程之间的执行顺序
8、案例-多线程实现文件夹多任务拷贝
1、需掌握python基础语法、python文件操作、python模块应用2、开发工具:pycharm、python3.6及以上版本
3、学习内容:进程、线程、多任务应用
多任务:是指在同一时间内执行多个任务
作用:充分利用CPU资源,提高任务执行效率
并行(在一段时间内真正的同时一起执行多个任务)
并发(在一段时间内交替去执行多个任务)
进程:进程是资源分配的最小单位,他是操作系统进行资源分配和调度运行的基本单位。理解:一个正在运行的一个程序就是一个进程。例如:正在运行的qq、wechat等,它们都是一个进程。
主进程:程序运行或默认创建一个进程,即主进程
子进程:程序运行之后又创建一个进程
1、创建进程 multiprocessing.Process(target,name,group) target:执行的目标任务名,即函数名(方法名) name:进程名 group:进程组,目前只能使用None 2、步骤 导入进程包 使用进程类创建进程对象 使用进程对象启动进程执行的指定任务
import multiprocessing
import time
def sing():
for i in range(3):
print('唱歌')
time.sleep(0.5)
def dance():
for i in range(3):
print('跳舞')
time.sleep(0.5)
if __name__=='__main__':
sing_process=multiprocessing.Process(target=sing)
dance_process=multiprocessing.Process(target=dance)
sing_process.start()
dance_process.start()
传参:以元组形式 args=(,) 类似位置传参 以字典形式 kwargs={'参数名':'参数值'} 类似关键字传参
import multiprocessing
import time
def sing(num,name):
for i in range(num):
print(name)
print('唱歌')
time.sleep(0.5)
def dance(num,name):
for i in range(num):
print(name)
print('跳舞')
time.sleep(0.5)
if __name__=='__main__':
# 元组方式给指定任务传参
sing_process=multiprocessing.Process(target=sing,args=(3,'小明'))
# 字典方式给指定任务传参
dance_process=multiprocessing.Process(target=dance,kwargs={'num':5,'name':'小李'})
sing_process.start()
dance_process.start()
进程编号的作用: 当程序中进程的数量越来越多时,如果没有办法区分主进程和子进程还有不同的子进程,那么就无法进行有效的进程管理,为了方便管理实际上每个进程都是有自己的编号的。 获取进程编号的两种方式: 获取当前进程编号 os.getpid() 获取当前父进程编号 os.getppid()
import os
import multiprocessing
import time
def sing(num,name):
print('唱歌进程的pid',os.getpid())
print('唱歌进程的父pid', os.getppid())
for i in range(num):
print(name)
print('唱歌')
time.sleep(0.5)
def dance(num,name):
print('跳舞进程的pid', os.getpid())
print('跳舞进程的父pid', os.getppid())
for i in range(num):
print(name)
print('跳舞')
time.sleep(0.5)
if __name__=='__main__':
print('主进程的pid', os.getpid())
# 子进程
# 元组方式给指定任务传参
sing_process=multiprocessing.Process(target=sing,args=(3,'小明'))
# 字典方式给指定任务传参
dance_process=multiprocessing.Process(target=dance,kwargs={'num':5,'name':'小李'})
# 启动子进程
sing_process.start()
dance_process.start()
主进程等所有子进程结束再结束 设置守护主进程:主进程退出后,子进程直接销毁,不再执行 子进程.daemon=True
import multiprocessing
import time
def work():
for i in range(10):
print('工作')
time.sleep(0.2)
if __name__=='__main__':
# 方式1
work_process = multiprocessing.Process(target=work, daemon=True)
# 方式2
# work_process.daemon = True
work_process.start()
time.sleep(1)
print('主进程完成')
需求分析: 目标文件夹是否存在,如果不存在就创建,存在则不创建 遍历源文件夹中所有文件,并拷贝到目标文件夹 采用进程实现多任务,并完成拷贝 实现步骤 定义源文件夹所在的路径,目标文件夹所在路径 创建目标文件夹 通过os.listdir获取源目录中的文件列表 遍历每个文件,定义一个函数,专门实现文件拷贝 采用进程实现多任务,完成高并发拷贝
import os
import multiprocessing
def copy_file(file_name, source_dir, dest_dir):
# 1 拼接源文件路径和目标文件路径
source_path = source_dir + '\\' + file_name
dest_path = dest_dir + '\\' + file_name
# 2 打开源文件和目标文件
with open(source_path, 'rb') as source_file:
with open(dest_path, 'wb') as dest_file:
# 3 循环读取源文件到目标路径
while True:
data = source_file.read(1024)
if data:
dest_file.write(data)
else:
break
if __name__ == '__main__':
# 1 定义源文件夹和目标文件夹
source_dir=r"D:\Documents\PyCharm WorkSpace\Python\Python多线程编程"
dest_dir=r"D:/Desktop/PYthon/test"
try:
os.mkdir(dest_dir)
except:
print('目标文件夹已近存在')
file_list=os.listdir(source_dir)
for file_name in file_list:
sub_process=multiprocessing.Process(target=copy_file,args=(file_name,source_dir,dest_dir))
sub_process.start()
实现多任务的另一种形式 线程是程序执行的最小单位 同属一个进程的多个线程共享进程所拥有的全部资源 进程是分配资源的最小单位,一旦创建一个进程就会分配一 -定的资源,就像跟两个人聊QQ就需要打开两个QQ软件--样是比较浪费资源的。 线程是程序执行的最小单位,实际上进程只负责分配资源,而利用这些资源执行程序的是线程,也就说进程是线程的 容器,-一个进程中最少有-一个线程来负责执行程序.同时线程自己不拥有系统资源,只需要--点儿在运行中必不可 少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源.这就像通过一个QQ软件(-一个进程)打开 两个窗口(两个线程)跟两个人聊天一样,实现多任务的同时也节省了资源.
线程的创建步骤 导入线程包 import threading 通过线程类创建进程对象 线程对象 = threading.Thread() 启动线程执行任务 线程对象.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__':
sing_threading=threading.Thread(target=sing)
dance_threading=threading.Thread(target=dance)
sing_threading.start()
dance_threading.start()
import threading
import time
def sing(num,name):
for i in range(num):
print(name)
print('唱歌')
time.sleep(0.5)
def dance(num,name):
for i in range(num):
print(name)
print('跳舞')
time.sleep(0.5)
if __name__=='__main__':
# 元组方式给指定任务传参
sing_threading = threading.Thread(target=sing,args=(3,'小明'))
# 字典方式给指定任务传参
dance_threading=threading.Thread(target=dance,kwargs={'num':5,'name':'小李'})
sing_threading.start()
dance_threading.start()
主线程等所有子线程执行结束后主线程再结束
import threading
import time
def work():
for i in range(10):
print('工作')
time.sleep(0.2)
if __name__=='__main__':
# 设置守护主进程:主进程退出后,子进程直接销毁,不再执行
# daemon = True
# work_threading.setDaemon(True)
work_threading=threading.Thread(target=work,daemon = True)
# work_threading.setDaemon(True)
work_threading.start()
time.sleep(1)
print('主进程完成')
无序,由CPU调度决定某个线程先执行
import time
import threading
def task():
time.sleep(1)
# current_thread 获取当前线程的线程对象
thread=threading.current_thread()
print(thread)
if __name__=="__main__":
for i in range(5):
sub_thread=threading.Thread(target=task)
sub_thread.start()
7、线程与进程的对比
关系对比 线程是依附在进程里面的,没有进程就没有线程 一个进程默认提供一条线程,进程可以创建多个线程 区别对此 创建进程的资源开销要比创建线程的资源开销要大 进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位 线程不能够独立执行,必须依存在进程中 优缺点对比 进程优缺点: 优点:可以用多核 缺点:资源开销大 线程优缺点: 优点:资源开销小 缺点:不可用多核
需求分析: 目标文件夹是否存在,如果不存在就创建,存在则不创建 遍历源文件夹中所有文件,并拷贝到目标文件夹 采用进程实现多任务,并完成拷贝 实现步骤 定义源文件夹所在的路径,目标文件夹所在路径 创建目标文件夹 通过os.listdir获取源目录中的文件列表 遍历每个文件,定义一个函数,专门实现文件拷贝 采用进程实现多任务,完成高并发拷贝
import os
import threading
def copy_file(file_name, source_dir, dest_dir):
# 1 拼接源文件路径和目标文件路径
source_path = source_dir + '\\' + file_name
dest_path = dest_dir + '\\' + file_name
# 2 打开源文件和目标文件
with open(source_path, 'rb') as source_file:
with open(dest_path, 'wb') as dest_file:
# 3 循环读取源文件到目标路径
while True:
data = source_file.read(1024)
if data:
dest_file.write(data)
else:
break
if __name__ == '__main__':
# 1 定义源文件夹和目标文件夹
source_dir=r"D:\Documents\PyCharm WorkSpace\Python\Python多线程编程"
dest_dir=r"D:/Desktop/PYthon/test"
try:
os.mkdir(dest_dir)
except:
print('目标文件夹已近存在')
file_list=os.listdir(source_dir)
for file_name in file_list:
sub_thread=threading.Thread(target=copy_file,args=(file_name,source_dir,dest_dir))
sub_thread.start()