文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Python中实现多线程 Threading 和多进程 Multiprocessing

2024-12-03 04:08

关注

本文转载自微信公众号「Piper蛋窝」,作者Piper蛋 。转载本文请联系Piper蛋窝公众号。

昨天晚上组会轮到我汇报技术内容,最近正在和 ray 以及 spark 打交道,索性讲一下并发和并行。反正大家都是管理学院的,平时很少接触这种,因此这个选题不大可能因为内容基础而贻笑大方。

本文摆一摆并发和并行。附上很简单的 Python 代码,涉及到自带库threading[1] 和 multiprocessing[2] 的使用。

并发和并行

咱们简单用多线程对应并发,多进程对应并行。多线程并发更强调充分利用性能;多进程并行更强调提升性能上限。

我用非常简单且不那么严谨的比喻来说明。

多线程

一个 CPU 相当于一个学生。

一个学生一周开一次组会,换句话说一周给老师汇报一次工作。

老师一般会给学生同时布置几个任务,比如做比赛、做项目、读论文,学生可能周一做做比赛、周二读读论文、周三做做项目... 到了组会,他就把三件事都拿出来汇报,老师很欣慰,因为在老师的视角里:学生这三件事是同时在做的。

多线程也是同一个道理,假设你的手机只有一块单核 CPU 。你的 CPU 这 0.01 秒用来播放音乐,下 0.01 秒用来解析网页... 在你的视角里:播放音乐和解析网页是同时进行的。你大可以畅快地边听音乐边网上冲浪

何谓充分利用性能? 如果这学生只有一项工作,那他这一周可能只需要花费两天来做任务,剩下时间摸鱼(针不搓,三点钟饮茶先!)。因此,我们用「多线程」来让学生实现『并发』,充分利用学生能力。

 

在实际情况中,多线程、高并发这些词语更多地出现在服务端程序里。比如一个网络连接由一个线程负责,一块 CPU 可以负责处理多个异步的请求,大大提升了 CPU 利用率。

多进程

多个 CPU ( CPU 的多核)相当于多个学生。

一个任务可以拆成几个任务相互协作、同时进行,则是多进程。

比如研究生课程,老师非得留个论文作业,都研究生了我去,留啥大作业。

那咱就多线程并行搞呗。确定了大概思路,剩下的一股脑写就行。咱队伍里一共甲乙丙丁四名同学,那就:

这是乙同学提出异议:不应该是先完成 Introduction 再写 Background ,一个个来嘛?

大哥,都研究生了嗷,作业糊弄糊弄差不多得了啊。让你写你就写。

可以预知,上述四部分同时进行,怎么也比一个人写四块要快。

 

所以说 多进程并行提升性能上限 。

在实际情况中,多进程更多地与高性能计算、分布式计算联系在一起。

Python 实现

首先声明咱的实验环境。

  1. > python --version 
  2. Python 3.8.5 

咱们设置个任务:求数的欧拉函数值。

  1. def euler_func(n: int) -> int
  2.     res = n 
  3.     i = 2 
  4.     while i <= n // i: 
  5.         if n % i == 0: 
  6.             res = res // i * (i - 1) 
  7.             while (n % i == 0): n = n // i 
  8.         i += 1 
  9.     if n > 1: 
  10.         res = res // n * (n - 1) 
  11.     return res 

求一个数的欧拉函数值可能很快,但是一堆数呢?

所以咱想着用并行完成这个任务。

咱们把任务分成三份。

  1. task1 = list(range(2, 50000, 3))  # 2, 5, ... 
  2. task2 = list(range(3, 50000, 3))  # 3, 6, ... 
  3. task3 = list(range(4, 50000, 3))  # 4, 7, ... 
  4.  
  5. def job(task: List): 
  6.     for t in task: 
  7.         euler_func(t) 

来看看平平无奇的正常串行。

  1. @timer 
  2. def normal(): 
  3.     job(task1) 
  4.     job(task2) 
  5.     job(task3) 

完成了 task1 再完成 task2 ... 行,没毛病。

看看多线程?

  1. import threading as th 
  2.  
  3. @timer 
  4. def mutlthread(): 
  5.     th1 = th.Thread(target=job, args=(task1, )) 
  6.     th2 = th.Thread(target=job, args=(task2, )) 
  7.     th3 = th.Thread(target=job, args=(task3, )) 
  8.  
  9.     th1.start() 
  10.     th2.start() 
  11.     th3.start() 
  12.  
  13.     th1.join() 
  14.     th2.join() 
  15.     th3.join() 

再看看多进程?

  1. import multiprocessing as mp 
  2.  
  3. @timer 
  4. def multcore(): 
  5.     p1 = mp.Process(target=job, args=(task1, )) 
  6.     p2 = mp.Process(target=job, args=(task2, )) 
  7.     p3 = mp.Process(target=job, args=(task3, )) 
  8.  
  9.     p1.start() 
  10.     p2.start() 
  11.     p3.start() 
  12.  
  13.     p1.join() 
  14.     p2.join() 
  15.     p3.join() 

上述代码的逻辑是这样的:

咱看看结果:

  1. if __name__ == '__main__'
  2.  
  3.     print("同步串行:"
  4.     normal() 
  5.  
  6.     print("多线程并发:"
  7.     mutlthread() 
  8.  
  9.     print("多进程并行:"
  10.     multcore() 
  11.  
  12. # 下面是结果 
  13. 同步串行: 
  14. timer: using 0.24116 s 
  15. 多线程并发: 
  16. timer: using 0.24688 s 
  17. 多进程并行: 
  18. timer: using 0.13791 s 

结果不太对,按理说,多进程并行的耗时应该是同步串行的三分之一,毕竟三个同等体量的任务在同时进行。

多线程并发比同步串行慢是应该的,因为多线程并发和同步串行的算力是一样的,但是多线程并发得在各个任务间来回切换,导致更慢。

你问 @timer 是什么意思?哦,这个是我写的修饰器,如下。

  1. def timer(func): 
  2.     @wraps(func) 
  3.     def inner_func(): 
  4.         t = time.time() 
  5.         rts = func() 
  6.         print(f"timer: using {time.time() - t :.5f} s"
  7.         return rts 
  8.     return inner_func 

 

不太明白『Python修饰器』的老铁,不如给我点个「在看」,再关注下我,咱们以后详细道来。

 

来源: Piper蛋窝内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯