Python之多线程部分

首先思考一下,我们平时在下载视频的时候是不是有单个下载和多个下载;

这里可以把下载一个视频的过程看成是一个任务;显然,多个视频一起下载,并行操作,cpu同时给多个任务分配资源,多个任务同时执行。

这样做有什么用?

提高了下载的效率;对于计算机中的cpu(中央处理器)提高了其处理数据的效率,节省了用户等待的时间。

并发的概念:
多个任务轮流或交替执行,例如:对于单核的cpu处理多任务,操作系统轮流让各个任务交替执行。并发需要满足的条件:任务数量大于cpu的核数,这是cpu只能单个任务切换(核数限制)。

并行的概念
多个任务真正地同时执行,例如:对于多核cpu处理多个任务,操作系统会给cpu的每个内核安排一个执行的任务,这样就可以实现多个任务同时执行,因为有能力靠多个内核执行多个任务。并行的条件:cpu的核数大于任务数

进程的概念:
进程是资源分配的最小单元,它是操作系统进行资源分配和调度运行的基本单位,即:程序在运行,例如:正在运行的qq、wechat 他们都是一个进程。

程序放在桌面上就仅仅是一个程序,但是我们双击它程序就运行起来了,一个进程就诞生了。

思考:

按照我们以前的程序运行思想,可定是先执行fun_a()这个函数 再执行fun_b()这个函数;

这两个函数是不同时间执行的,分有执行顺序,先执行A任务再执行任务B。

如果人这个两个函数同时执行,是不是就提升了代码执行的效率,那有没有什么办法呢?

 程序运行时会默认创建一个主进程,我们使用多进程技术就可以分为多个子进程,上图中的fun_a和fun_b函数就可以看做两个子进程,我们就可以让他们同时执行。

Python的第三方库特别的强大,有一个多线程包 multiprocessing

进程的创建步骤

1.导入进程包

import multiprocessing

2、创建进程对象

进程对象名=函数名_process=multiprocessing.Process(target=函数名,传参) target(函数名方法名)

传参分为:元组传参(...,)[可以看做函数中的位置参数传递] 字典传参({参数名:值...})[可以看做是关键字传参]

3、启动进程执行任务

进程对象.start()

代码展示多任务并行:

 可以清楚地看到这两个函数同时执行了,由多进程对象控制。

 进程执行带有参数的任务:

分为两中种情况:

  1. 位置参数:args,以元组的方式给执行的任务传参   
  2. 关键字参数:kwargs,以字典的方式给执行的任务传参

利于传入参数为sing()函数的循环次数:

 

 定义谁在唱歌的函数传入张三,唱5次歌:

 解释各个参数的意思
target:指定进程执行的函数名

args:使用元组方式传参  args=(,) 这个','不能省略;

kwargs:使用字典方式传参 kwargs={..:..,..:.}

要点注意:
元祖方式传参:元组方式传参一定要和参数的顺序保持一致。

字典方式传参:字典传参字典中的key一定要和参数名保持一致,每个顺序的顺序不做要求。

获取进程编号:
当进程的数量越来越多时,为了方便管理和查询需要给每个进程编号。

获取进程编号的两种方式:

需要导入os模块 通过计算机系统(任务管理器)获取

import os

tar=os.getpid()

tar=os.getppid()

  1. os.getpid()    获取当前进程编号
  2. os.getppid()   获取当前父进程编号

代码演示:

 可以看到两个子进程的父进程的pid完全相同,这不就间接地说明了两个子进程是由一个主进程切分的嘛,这里的测试结果有点差异,两个子进程的pid没有相同.

进程的注意点:

主进程会等待所有的子进程执行完毕后在结束:

代码结果演示:

 设置主进程,守护主进程

主进程结束后程序就执行了;

只需在子程序开始(对象.start())添加一行代码: 对象.daemon=True

 

 知识要点:
为了保证子进程能够正常运行,主进程会等所有子进程结束后再销毁(父亲的关爱),设置守护守护主进程(父亲结束,孩子自动结束)。

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

主进程会等子进程,除非设置了守护主进程

案例:文件夹高并发cpoy器:

简单就三步:

1、创建目标文件下的目录 (异常处理)

2、文件读写(拷贝)操作

3、利用多线程处理操作,提高效率

代码结果演示:
拷贝函数准备:

 程序入口函数:

copy文件下的文件的关键点

首先,是确定source和destiation的目录;

其次,拿到source目录下的所有文件名(os.listdir()方法),利用循环引出各个文件;

最后,多进程技术结合 循环 确立source和destiation的具体路径再结合文件操作copy(读写)。

接下来,让我们来看看线程的知识:线程和进程类似

为什么使用多线程?
进程是分配资源的最小单位,一旦创建一个进程就会分配一定的资源,就像跟两个人聊QQ就需要打开两个QQ软件一样比较浪费资源的。

线程是程序执行的最小单位,实际上进程只负责分配资源,而利用这些资源执行程序的是线程,也就是说进程包含线程 进程大 线程小。一个进程至少有一个线程来负责执行程序,同时线程不拥有自己的系统资源,开销的资源特别少,但是它可以与同属一个进程的其他线程共享所有所拥有的全部资源,例如:通过QQ软件(一个进程)打开两个窗口(两个线程)跟两个人聊天一样,实现任务的同时。总之,线程需要的系统资源少,既提高效率又节省资源。

多线程同样使用多线程完成


 

多线程也是实现多任务的一种方式,与多进程类似;

线程是程序执行的最小单位;

同属一个进程的多个线程共享进程所拥有的全部资源,由cpu调度分配。

线程的创建步骤:
1、导入线程模块

import threading

2、通过线程类创建线程对象

线程对象=threading.Thread(target=函数名/方法名)

3、线程开始

线程对象.start()

代码结果演示:

 线程传参知识:
元组方式传参:元组方式传参一定要和参数的顺序保持一致;

字典方式传参:字典的ke一定要和函数的形参对应。

注意:主线程会等子线程执行完毕才结束代码运行。

与进程类似,我们可以守护主线程来改变这种模式,主线程结束整个代码就结束执行。

设置守护主线程:两种方式:

1、在线程对象开始执行前增加 进程对象.daemon=True 

2、在传入参数时(targrt=方法名,daemon=True)

代码结果演示:


总结:

通常情况下,主线程会等待子线程执行完之后再结束主线程 ;

可以采用设置守护主线程的方式改变这种局面(

(1)线程对象.daemon=True

(2)传参的时候进行,线程对象.Thread(target=函数名,daemon=True)

)从此主线程结束,子线程就结束。

与进程获取进程编号一样(getpid()/getppid()),获取当前的线程对象:

代码结果演示:

 

 线程之间执行是无序的,是由cpu调度决定某个线程先执行的。

最后的最后,让我们来看看进程和线程的对比

  • 关系对比:线程依附进程,没有进程就没有线程    一个进程默认只有一个线程,进程可以创建多个线程。
  • 区别对比:进程的资源开销会比线程的多 (进程是操作系统分配的基本单位/线程是cpu调度的基本单位) 线程不能构独立执行、必须依存在进程中,简而言之,进程存在,线程才能存在。
  • 优缺点对比:进程:可以多核,资源开销大 ;线程:不能多核,资源开销少。

利用线程的方式,开发一个文件夹高并发copy器

使用多线层也可以实现多任务拷贝提高程序性能。
需求:与进程版copy一样

代码与结果展示:

 

 

 

 这就是进程与线程的基本知识了,希望大家学有所获,谢谢大家的阅读!!!

关键点:
没有进程就没有线程、进程可以多核但是资源开销大;线程资源开销但是不能多核;

python多线(进)程强大在任务执行处理方面;

进程(multiprocessing) 线程(threading)

多任务实现三步法:

  1. 导包
  2. 创建进程或者线程对象
  3. 进程对象或者线程对象开始

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值