一、进程

进程的创建步骤
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‘:

  1. # 2、使用进程类创建进程对象
  2. sing_process = multiprocessing.Process(target=sing)
  3. dance_process = multiprocessing.Process(target=dance)
  4. # 3、使用进程对象启动进程执行指定任务
  5. sing_process.start()
  6. 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():

  1. # 获取当前进程的编号
  2. print("work进程编号", os.getpid())
  3. # 获取父进程的编号
  4. print("work父进程的编号:", os.getppid())

进程的注意点
主进程会等待所有的子进程执行结束再结束
import multiprocessing
import time
def work():
for i in range(10):
print(“工作中。。。”)
time.sleep(0.2)

if name == ‘main‘:

  1. # 创建子进程
  2. work_process = multiprocessing.Process(target=work)
  3. work_process.start()
  4. # 让主进程等待一秒钟
  5. time.sleep(1)
  6. print("主进程执行完成了啦")
  7. # 总结:主进程会等待所有的子进程执行完成以后程序再退出

设置守护主进程

设置守护主进程,主进程退出后子进程直接销毁,不再执行子进程中的代码

work_process.daemon = True

为了保证子进程能够正常的运行,主进程会等所有的子进程执行完成以后再销毁,设置守护主进程的目的是主进程退出子进程销毁,不让主进程再等待子进程去执行。

设置守护主进程方式:子进程对象.daemon = True

传智教学视频文件夹高并发copy器

案例:需求分析
①目标文件夹是否存在,如果不存在就创建,如果存在则不创建
②遍历源文件夹中所有文件,并拷贝到目标文件夹
③采用进程实现多任务,完成高并发拷贝

案例:实现步骤
1、定义源文件夹所在的路径、目标文件夹所有路径

1、定义源文件目录和目标文件夹的目录

source_dir = “python教学视频”
dest_dir = “/home/python/桌面/test”
2、创建目标文件夹
try:

  1. # 2、创建目标文件夹目录
  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:

  1. # copy_work(file_name,source_dir,source_dir)
  2. sub_process = multiprocessing.Process(target=copy_work,args=(file_name,source_dir,dest_dir))
  3. sub_process.start()

文件拷贝函数实现步骤
1、拼接源文件和目标文件夹所在的路径

def copy_file(file_name, source_dir, dest_dir):

  1. # 拼接路径
  2. source_path = source_dir+"/"+file_name
  3. 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:

  1. # 循环读取数据
  2. file_data = source_file.read(1024)
  3. if file_data:
  4. # 循环写入到目标文件
  5. dest_file.write(file_data)
  6. else:
  7. 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器
略(代码和多线程基本一致)。。。

使用多线程也可以实现多任务拷贝提高系统性能

更多相关文章

  1. Android(安卓)Zygote进程和SystemServer进程启动过程
  2. Android强制在主线程进行网络请求
  3. Android之NetworkOnMainThreadException异常
  4. android一个简单的线程实例
  5. android 手电筒
  6. Timer和TimerTask的知识点
  7. android hander 线程用法
  8. Android(安卓)ANR 分析
  9. Android之Widget

随机推荐

  1. 尽管referesh,jQuery格式化不适用于ajax数
  2. html中文本域选中后会出现蓝边框
  3. 如何使用CSS将表放在页面的中心?
  4. js限制文本框只能输入数字方法
  5. jquery validate (jquery 验证的三种方式
  6. JQUERY组装对象并调用自身函数改变自己的
  7. jquery获取input值的各种情况
  8. jQuery File Upload 单页面多实例的实现
  9. jquery每个添加类中间延迟
  10. Jquery ajax回调函数不执行