Python多线程编程
一、进程
进程的创建步骤
1、导入进程包
import multiprocessing
2、通过进程类创建进程对象
进程对象 = multipreocessing.Process()
3、启动进程执行对象
进程对象.start()
通过进程类创建进程对象
进程对象 = multiprocessing.Process(target=任务名)
参数名 说明
target 执行的目标任务名,这里指的是函数名(方法名)
name 进程名,一般不用设置
group 进程组,目前只能使用None
进程创建与启动的代码
创建子进程
sing_process = multiprocessing.Process(target=sing)
创建子进程
dance_process = multiprocessing.Process(target=dance)
启动进程
sing_process.start()
dance_process.start()
使用多进程实现多任务
1、导入进程包
2、使用进程类创建进程对象
3、使用进程对象启动进程执行指定任务
1、导入进程包
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‘:
# 2、使用进程类创建进程对象
sing_process = multiprocessing.Process(target=sing)
dance_process = multiprocessing.Process(target=dance)
# 3、使用进程对象启动进程执行指定任务
sing_process.start()
dance_process.start()
进程执行带有参数的任务
参数名 说明
args 以元组的方式给执行任务传参
kwargs 以字典方式给执行任务传参
args参数的使用
target: 进程执行的函数名
args:表示以元组的方式给函数传参
sing_process = multiprocessing.Process(target=sing,args=(3,))
sing_process.start()
元组方式传参:元组方式传参一定要和参数的顺序保持一致。
字典方式传参:字典方式传参字典中的key一定要和参数名保持一致。
进程编号的作用:
当程序中进程的数量越来越多时,如果没有办法区分主进程和子进程还有不同的子进程,那么就无法进行有效的进程管理,为了方便管理实际上每个进程都是有自己编号的。
获取进程编号的两种方式:
1、获取当前进程编号
os.getpid()
2、获取当前父进程编号
os.getppid()
os.getpid()的使用
import os
pid = os.getpid()
print(pid)
os.getppid()的使用
import os
def work():
# 获取当前进程的编号
print("work进程编号", os.getpid())
# 获取父进程的编号
print("work父进程的编号:", os.getppid())
进程的注意点
主进程会等待所有的子进程执行结束再结束
import multiprocessing
import time
def work():
for i in range(10):
print(“工作中。。。”)
time.sleep(0.2)
if name == ‘main‘:
# 创建子进程
work_process = multiprocessing.Process(target=work)
work_process.start()
# 让主进程等待一秒钟
time.sleep(1)
print("主进程执行完成了啦")
# 总结:主进程会等待所有的子进程执行完成以后程序再退出
设置守护主进程
设置守护主进程,主进程退出后子进程直接销毁,不再执行子进程中的代码
work_process.daemon = True
为了保证子进程能够正常的运行,主进程会等所有的子进程执行完成以后再销毁,设置守护主进程的目的是主进程退出子进程销毁,不让主进程再等待子进程去执行。
设置守护主进程方式:子进程对象.daemon = True
传智教学视频文件夹高并发copy器
案例:需求分析
①目标文件夹是否存在,如果不存在就创建,如果存在则不创建
②遍历源文件夹中所有文件,并拷贝到目标文件夹
③采用进程实现多任务,完成高并发拷贝
案例:实现步骤
1、定义源文件夹所在的路径、目标文件夹所有路径
1、定义源文件目录和目标文件夹的目录
source_dir = “python教学视频”
dest_dir = “/home/python/桌面/test”
2、创建目标文件夹
try:
# 2、创建目标文件夹目录
os.mkdir(dest_dir)
except:
print(“目标文件夹已经存在,未创建~”)
3、通过os.listdir 获取源目录中的文件列表
3、列表得到所有的源文件夹中的文件
file_list = os.listdir(source_dir)
print(file_list)
4、遍历每个文件,定义一个函数,专门实现文件拷贝
4、for 循环,依次拷贝每个文件
for file_name in file_list:
copy_work(file_name,source_dir,source_dir)
4、采用进程实现多任务,完成高并发拷贝
4、for 循环,依次拷贝每个文件
for file_name in file_list:
# copy_work(file_name,source_dir,source_dir)
sub_process = multiprocessing.Process(target=copy_work,args=(file_name,source_dir,dest_dir))
sub_process.start()
文件拷贝函数实现步骤
1、拼接源文件和目标文件夹所在的路径
def copy_file(file_name, source_dir, dest_dir):
# 拼接路径
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:
# 循环读取数据
file_data = source_file.read(1024)
if file_data:
# 循环写入到目标文件
dest_file.write(file_data)
else:
break
二、线程
为什么使用多线程?
进程是分配资源的最小单位,一旦创建一个进程就会分配一定的资源,就像跟两个人聊QQ就需要打开两个QQ软件一样是比较浪费资源的。
线程是程序执行的最小单位,实际上进程只负责分配资源,而利用这些资源执行程序的是线程,也就说进程是线程的容器,一个进程中最少有一个线程来负责执行程序,同时线程自己不拥有系统资源,只需要一点儿在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源,这就像通过一个QQ软件(一个进程)打开两个窗口(两个线程)跟两个人聊天一样,实现多任务的同时也节省了资源。
多线程是Python程序中实现多任务的一种方法
线程是程序执行的最小单位
同属一个进程的多个线程共享进程所拥有的所有资源
线程的创建步骤
1、导入线程模块
import threading
2、通过线程类创建线程对象
线程对象 = threading.Thread(target=任务名)
3、启动线程对象
线程对象.start()
通过线程类创建线程对象
线程对象 = threading.Thread(target=任务名)
参数名 说明
target 执行的目标任务名,这里指的是函数名(方法名)
name 线程名,一般不用设置
group 线程组,目标只能使用None
线程创建与启动的代码
创建子线程
sing_thread = threading.Thread(target=sing)
创建子线程
dance_thread = threading.Thread(target=dance)
启动线程
sing_thread.start()
dance_thread.start()
线程执行带有参数的任务
参数名 说明
args 以元组的方式给执行任务传参
kwargs 以字典方式给执行任务传参
args参数的使用
target:线程执行的函数名
args:表示以元组的方式给函数传参
sing_thread = threading.Thread(target=sing,args=(3,))
sing_thread.start()
kwargs参数的使用
target:线程执行的函数名
kwargs:表示以字典的方式给函数传参
dance_thread = threading.Thread(target=sing,kwargs={“count”:3})
开启线程
dance_thread.start()
元组方式传参:元组方式传参一定要和参数的顺序保持一致。
字典方式传参:字典方式传参字典中的key一定要和参数名保持一致。
主线程和子线程的结束顺序
对比进程
主线程会等待所有的子线程执行结束后主线程再结束
设置守护主线程
要想主线程不等待子线程执行完成可以设置守护主线程
设置守护主线程方式1,daemon=true 守护主线程
work_thread = threading.Thread(target=work,daemon=True)
设置守护主线程方式2
work_thread.setDaemon(Ture)
work_thread.start()
主线程延时1秒
time.sleep(1)
print(“over”)
主线程会等待所有的子线程执行结束再结束,除非设置子线程守护主线程
设置守护主线程有两种方式:
1.threading.Thread(target=work,daemon=True)
2.线程对象.setDaemon(True)
线程之间执行时无序的
for i in range(5):
sub_thread = threading.Thread(target=task)
sub_thread.start()
获取当前的线程信息:
通过current_thread方法获取线程对象
current_thread = threading.current_thread()
通过current_thread对象可以知道线程的相关信息,例如被创建的顺序
print(current_thread)
线程之间执行时无序的,是由CPU调度决定某个线程先执行的。
进程和线程对比
关系对比
1.线程是依附在进程里面的,没有进程就没有线程。
2.一个进程默认提供一条线程,进程可以创建多个线程。
区别对比
1.创建进程的资源开销要比创建线程的资源开销要大
2.进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位
3.线程不能够独立执行,必须依存在进程中
优缺点对比
1.进程优缺点:
优点:可以用多核
缺点:资源开销大
2.线程优缺点:
优点:资源开销小
缺点:不能使用多核
传智教学视频文件夹高并发copy器
略(代码和多线程基本一致)。。。
使用多线程也可以实现多任务拷贝提高系统性能
更多相关文章
- Android(安卓)Zygote进程和SystemServer进程启动过程
- Android强制在主线程进行网络请求
- Android之NetworkOnMainThreadException异常
- android一个简单的线程实例
- android 手电筒
- Timer和TimerTask的知识点
- android hander 线程用法
- Android(安卓)ANR 分析
- Android之Widget