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

创新互联-成都网站建设公司,专注成都网站设计、成都网站制作、网站营销推广,申请域名,网页空间,网站托管维护有关企业网站制作方案、改版、费用等问题,请联系创新互联。
昨天晚上组会轮到我汇报技术内容,最近正在和 ray 以及 spark 打交道,索性讲一下并发和并行。反正大家都是管理学院的,平时很少接触这种,因此这个选题不大可能因为内容基础而贻笑大方。
本文摆一摆并发和并行。附上很简单的 Python 代码,涉及到自带库threading[1] 和 multiprocessing[2] 的使用。
咱们简单用多线程对应并发,多进程对应并行。多线程并发更强调充分利用性能;多进程并行更强调提升性能上限。
我用非常简单且不那么严谨的比喻来说明。
一个 CPU 相当于一个学生。
一个学生一周开一次组会,换句话说一周给老师汇报一次工作。
老师一般会给学生同时布置几个任务,比如做比赛、做项目、读论文,学生可能周一做做比赛、周二读读论文、周三做做项目... 到了组会,他就把三件事都拿出来汇报,老师很欣慰,因为在老师的视角里:学生这三件事是同时在做的。
多线程也是同一个道理,假设你的手机只有一块单核 CPU 。你的 CPU 这 0.01 秒用来播放音乐,下 0.01 秒用来解析网页... 在你的视角里:播放音乐和解析网页是同时进行的。你大可以畅快地边听音乐边网上冲浪
何谓充分利用性能? 如果这学生只有一项工作,那他这一周可能只需要花费两天来做任务,剩下时间摸鱼(针不搓,三点钟饮茶先!)。因此,我们用「多线程」来让学生实现『并发』,充分利用学生能力。
在实际情况中,多线程、高并发这些词语更多地出现在服务端程序里。比如一个网络连接由一个线程负责,一块 CPU 可以负责处理多个异步的请求,大大提升了 CPU 利用率。
多个 CPU ( CPU 的多核)相当于多个学生。
一个任务可以拆成几个任务相互协作、同时进行,则是多进程。
比如研究生课程,老师非得留个论文作业,都研究生了我去,留啥大作业。
那咱就多线程并行搞呗。确定了大概思路,剩下的一股脑写就行。咱队伍里一共甲乙丙丁四名同学,那就:
这是乙同学提出异议:不应该是先完成 Introduction 再写 Background ,一个个来嘛?
大哥,都研究生了嗷,作业糊弄糊弄差不多得了啊。让你写你就写。
可以预知,上述四部分同时进行,怎么也比一个人写四块要快。
所以说 多进程并行提升性能上限 。
在实际情况中,多进程更多地与高性能计算、分布式计算联系在一起。
首先声明咱的实验环境。
- > python --version
 - Python 3.8.5
 
咱们设置个任务:求数的欧拉函数值。
- def euler_func(n: int) -> int:
 - res = n
 - i = 2
 - while i <= n // i:
 - if n % i == 0:
 - res = res // i * (i - 1)
 - while (n % i == 0): n = n // i
 - i += 1
 - if n > 1:
 - res = res // n * (n - 1)
 - return res
 
求一个数的欧拉函数值可能很快,但是一堆数呢?
所以咱想着用并行完成这个任务。
咱们把任务分成三份。
- task1 = list(range(2, 50000, 3)) # 2, 5, ...
 - task2 = list(range(3, 50000, 3)) # 3, 6, ...
 - task3 = list(range(4, 50000, 3)) # 4, 7, ...
 - def job(task: List):
 - for t in task:
 - euler_func(t)
 
来看看平平无奇的正常串行。
- @timer
 - def normal():
 - job(task1)
 - job(task2)
 - job(task3)
 
完成了 task1 再完成 task2 ... 行,没毛病。
看看多线程?
- import threading as th
 - @timer
 - def mutlthread():
 - th1 = th.Thread(target=job, args=(task1, ))
 - th2 = th.Thread(target=job, args=(task2, ))
 - th3 = th.Thread(target=job, args=(task3, ))
 - th1.start()
 - th2.start()
 - th3.start()
 - th1.join()
 - th2.join()
 - th3.join()
 
再看看多进程?
- import multiprocessing as mp
 - @timer
 - def multcore():
 - p1 = mp.Process(target=job, args=(task1, ))
 - p2 = mp.Process(target=job, args=(task2, ))
 - p3 = mp.Process(target=job, args=(task3, ))
 - p1.start()
 - p2.start()
 - p3.start()
 - p1.join()
 - p2.join()
 - p3.join()
 
上述代码的逻辑是这样的:
咱看看结果:
- if __name__ == '__main__':
 - print("同步串行:")
 - normal()
 - print("多线程并发:")
 - mutlthread()
 - print("多进程并行:")
 - multcore()
 - # 下面是结果
 - 同步串行:
 - timer: using 0.24116 s
 - 多线程并发:
 - timer: using 0.24688 s
 - 多进程并行:
 - timer: using 0.13791 s
 
结果不太对,按理说,多进程并行的耗时应该是同步串行的三分之一,毕竟三个同等体量的任务在同时进行。
多线程并发比同步串行慢是应该的,因为多线程并发和同步串行的算力是一样的,但是多线程并发得在各个任务间来回切换,导致更慢。
你问 @timer 是什么意思?哦,这个是我写的修饰器,如下。
- def timer(func):
 - @wraps(func)
 - def inner_func():
 - t = time.time()
 - rts = func()
 - print(f"timer: using {time.time() - t :.5f} s")
 - return rts
 - return inner_func
 
不太明白『Python修饰器』的老铁,不如给我点个「在看」,再关注下我,咱们以后详细道来。
                分享标题:Python中实现多线程Threading和多进程Multiprocessing
                
                标题链接:http://www.csdahua.cn/qtweb/news37/494737.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网