专栏首页小一的数据分析之路Python入门进阶教程-多线程与多进程

Python入门进阶教程-多线程与多进程

作者:一叶

介绍:放不下灵魂的搬砖者

全文共1935字,阅读全文需8分钟

Python版本3.8.0,开发工具:Pycharm

试想一下当你有1w个小文件需要处理,假设每个文件读取处理到写入需要1秒,

那么你处理完所以文件会需要两个多小时。

但是如果你可以同时开启四个任务处理1w 个文件,每个任务平均处理2500个。

这个时候你的时间可以压缩在一小时以内。

如何同时对一个文件夹开启四个任务同时处理不同的任务,而不会产生冲突?接下来我们一起了解一下多线程和多进程。

进程与线程

从一定意义上讲,进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,进程包含多个线程在运行。 进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。线程是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源。

01

Python多线程

Python 中提供两个标准库 thread 和 threading 用于对线程的支持,但 Python3 中已放弃对 thread 的支持,所以接下来均以 threading 为例。

Python中有两种方式实现线程:

  • 实例化一个 threading.Thread 的对象,并传入一个初始化函数对象作为线程执行的入口;
  • 继承 threading.Thread,并重写 run 函数;
 1# 第一种实现线程的方法
 2import threading
 3# my_fun为自定义函数,args为自定义函数的参数
 4thread1 = threading.Thread(target=my_fun, args=('This is thread 1',))
 5thread2 = threading.Thread(target=my_fun, args=('This is thread 2',))
 6# 启动线程
 7thread1.start()
 8thread2.start()
 9
10
11# 第二中实现线程的方法
12class MyThread(threading.Thread):
13    # step 1: call base __init__ function
14    def __init__(self, thread_name):
15        super(CustomThread, self).__init__(name=thread_name)
16        self._tname = thread_name
17    # step 2: overide run function
18    def run(self):
19        print("This is %s running...." % self._tname)
20# 实例化MyThread
21thread1 = MyThread("thread 1")
22thread2 = MyThread("thread 2")
23# 启动线程
24thread1.start()
25thread2.start()

注:

  • 两种方式创建线程,指定的参数最终都会传给threading.Thread类;
  • 传给线程的目标函数是在基类Thread的run函数体中被调用的,如果run没有被重写的话。

threading.Thread提供的线程对象方法和属性:

1. start():创建线程后通过start启动线程,等待CPU调度,为run函数执行做准备;
2. run():线程开始执行的入口函数,函数体中会调用用户编写的target函数,或者执行被重载的run函数;
3. join([timeout]):阻塞挂起调用该函数的线程,直到被调用线程执行完成或超时。通常会在主线程中调用该方法,等待其他线程执行完成。
4. name、getName()&setName():线程名称相关的操作;
5. ident:整数类型的线程标识符,线程开始执行前(调用start之前)为None;
6. isAlive()、is_alive():start函数执行之后到run函数执行完之前都为True;
7. daemon、isDaemon()&setDaemon():守护线程相关。

02

Python多进程

Python 提供 multiprocessing 用于创建多进程

创建进程的方式和创建线程的方式类似:

  • 实例化一个 multiprocessing.Process 的对象,并传入一个初始化函数对象作为新建进程执行入口;
  • 继承 multiprocessing.Process,并重写 run 函数;
 1# 第一种实现进程的方法
 2from multiprocessing import Process
 3
 4# my_fun为自定义函数,args为自定义函数的参数
 5process1 = Process(target=my_fun, args=('This is process 1',))
 6process2 = Process(target=my_fun, args=('This is process 2',))
 7# 启动线程
 8process1.start()
 9process2.start()
10# join()方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步。
11process1.join()
12process2.join()
13
14
15# 第二中实现进程的方法
16from multiprocessing import Process  
17
18class MyProcess(Process):
19    def __init__(self, p_name, target=None):
20        # step 1: call base __init__ function()
21        super().__init__(name=p_name, target=target, args=(p_name,))
22
23    def run(self):
24        # step 2:
25        print("Process name: %s, pid: %s " % (self.name, os.getpid()))
26
27if __name__ == '__main__':
28    # 实例化MyProcess
29    process1 = MyProcess("process 1")
30    process2 = MyProcess("process 2")
31    # 启动进程
32    process1.start()
33    process2.start()
34    process1.join()
35    process2.join()

03

进程 VS. 线程

是否采用多任务需要考虑任务的类型,我们可以把任务分为CPU密集型和IO密集型。

  • CPU密集型任务的特点是要进行大量的计算,消耗CPU资源,比如计算圆周率、对视频进行高清解码等等,全靠CPU的运算能力。
  • 涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成

总结:

  • CPU密集型:程序需要占用CPU进行大量的运算和数据处理;
  • I/O密集型:程序中需要频繁的进行I/O操作;例如网络中socket数据传输和读取等;

由于Python多线程并不是并行执行,因此较适合与I/O密集型程序,多进程并行执行适用于CPU密集型程序;


根据任务的需求选择相应的多任务方式,在多文件数据操作、爬虫等任务时相当实用!

下节将介绍Python JSON操作

Python系列

Python系列会持续更新,从基础入门到进阶技巧,从编程语法到项目实战。若您在阅读的过程中发现文章存在错误,烦请指正,非常感谢;若您在阅读的过程中能有所收获,欢迎一起分享交流。

如果你也想和我一起学习Python,关注我吧!

学习Python,我们不只是说说而已

End

本文分享自微信公众号 - 知秋小梦(little_dream_2019),作者:一叶

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 《大话机器学习算法》决策树—实战项目

    如果你还不知道决策树算法,你可以选择和韩梅梅同学一起边相亲边学习决策树(手动狗头):

    知秋小一
  • 写了个自动化脚本,每日更新疫情数据

    先说明一下,这是一篇爬虫+分析+自动化的文章,并不是上节说到的 NumPy 系列文章,NumPy 系列请期待下节内容。

    知秋小一
  • 《Hello NumPy》系列-数据类型与创建

    NumPy(Numerical Python 的简称)是高性能科学计算和数据分析的基础包,是 SciPy、Pandas 等数据科学的基础库,它所提供的数据结构比...

    知秋小一
  • Java 多线程详解(五)------线程的声明周期

    Java 多线程详解(一)------概念的引入:https://cloud.tencent.com/developer/article/1012542 Jav...

    IT可乐
  • Dubbo线程模型

    dubbo线程模型包括线程模型策略和dubbo线程池策略两个方面,下面就依次进行分析。

    luoxn28
  • 「JAVA」线程生命周期分阶段详解,哲学家们也深感死锁难解

    每个事物都有其生命周期,也就是事物从出生开始到最终消亡这中间的整个过程;在其整个生命周期的历程中,会有不同阶段,每个阶段对应着一种状态,比如:人的一生会经历从婴...

    老夫编程说
  • 线程的生命周期

    线程的六种状态: NEW、RUNNABLE、BIOCKED、WAITING、TIME_WAITING、TERMINATED。

    用户7386338
  • 「JAVA」线程生命周期分阶段详解,哲学家们深感死锁难解

    每个事物都有其生命周期,也就是事物从出生开始到最终消亡这中间的整个过程;在其整个生命周期的历程中,会有不同阶段,每个阶段对应着一种状态,比如:人的一生会经历从婴...

    老夫编程说
  • 没想到,这么简单的线程池用法,深藏这么多坑!

    生产有个对账系统,每天需要从渠道端下载对账文件,然后开始日终对账。这个系统已经运行了很久,前两天突然收到短信预警,没有获取渠道端对账文件。

    andyxh
  • Java 多线程(8)---- 线程组和 ThreadLocal

    在上面文章中,我们从源码的角度上解析了一下线程池,并且从其 execute 方法开始把线程池中的相关执行流程过了一遍。那么接下来,我们来看一个新的关于线程的知识...

    指点

扫码关注云+社区

领取腾讯云代金券