2024年Python最全Python 的多线程与多进程_np,2024年最新一线互联网java面试核心知识点

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

初学者的并行编程指南

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在参加 Kaggle 的 Understanding the Amazon from Space 比赛时,我试图对自己代码的各个部分进行加速。速度在 Kaggle 比赛中至关重要。高排名常常需要尝试数百种模型结构与超参组合,能在一个持续一分钟的 epoch 中省出 10 秒都是一个巨大的胜利。

让我吃惊的是,数据处理是最大的瓶颈。我用了 Numpy 的矩阵旋转、矩阵翻转、缩放及裁切等操作,在 CPU 上进行运算。Numpy 和 Pytorch 的 DataLoader 在某些情况中使用了并行处理。我同时会运行 3 到 5 个实验,每个实验都各自进行数据处理。但这种处理方式看起来效率不高,我希望知道我是否能用并行处理来加快所有实验的运行速度。

什么是并行处理?

简单来说就是在同一时刻做两件事情,也可以是在不同的 CPU 上分别运行代码,或者说当程序等待外部资源(文件加载、API 调用等)时把“浪费”的 CPU 周期充分利用起来提高效率。

下面的例子是一个“正常”的程序。它会使用单线程,依次进行下载一个 URL 列表的内容。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下面是一个同样的程序,不过使用了 2 个线程。它把 URL 列表分给不同的线程,处理速度几乎翻倍。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果你对如何绘制以上图表感到好奇,可以参考源码,下面也简单介绍一下:

  1. 在你函数内部加上一个计时器,并返回函数执行的起始与结束时间
URLS = [url1, url2, url3, ...]
def download(url, base):
    start = time.time() - base
    resp = urlopen(url)
    stop = time.time() - base
    return start,stop
  1. 单线程程序的可视化如下:多次执行你的函数,并将多个开始结束的时间存储下来
results = [download(url, 1) for url in URLS]
  1. 将 [start, stop] 的结果数组进行转置,绘制柱状图
def visualize_runtimes(results):
    start,stop = np.array(results).T
    plt.barh(range(len(start)), stop-start, left=start)
    plt.grid(axis=’x’)
    plt.ylabel("Tasks")
    plt.xlabel("Seconds")

多线程的图表生成方式与此类似。Python 的并发库一样可以返回结果数组。

进程 vs 线程

一个进程就是一个程序的实例(比如 Jupyter notebook 或 Python 解释器)。进程启动线程(子进程)来处理一些子任务(比如按键、加载 HTML 页面、保存文件等)。线程存活于进程内部,线程间共享相同的内存空间。

举例:Microsoft Word
当你打开 Word 时,你其实就是创建了一个进程。当你开始打字时,进程启动了一些线程:一个线程专门用于获取键盘输入,一个线程用于显示文本,一个线程用于自动保存文件,还有一个线程用于拼写检查。在启动这些线程之后,Word 就能更好的利用空闲的 CPU 时间(等待键盘输入或文件加载的时间)让你有更高的工作效率。

进程

  • 由操作系统创建,以运行程序
  • 一个进程可以包括多个线程
  • 两个进程可以在 Python 程序中同时执行代码
  • 启动与终止进程需要花费更多的时间,因此用进程比用线程的开销更大
  • 由于进程不共享内存空间,因此进程间交换信息比线程间交换信息要慢很多。在 Python 中,用序列化数据结构(如数组)的方法进行信息交换会花费 IO 处理级别的时间。

线程

  • 线程是在进程内部的类似迷你进程的东西
  • 不同的线程共享同样的内存空间,可以高效地读写相同的变量
  • 两个线程不能在同一个 Python 程序中执行代码(有解决这个问题的方法*

CPU vs 核

CPU,或者说处理器,管理着计算机最基本的运算工作。CPU 有一个或着多个,可以让 CPU 同时执行代码。

如果只有一个核,那么对 CPU 密集型任务(比如循环、运算等)不会有速度的提升。操作系统需要在很小的时间片在不同的任务间来回切换调度。因此,做一些很琐碎的操作(比如下载一些图片)时,多任务处理反而会降低处理性能。这个现象的原因是在启动与维护多个任务时也有性能的开销。

Python 的 GIL 锁问题

CPython(python 的标准实现)有一个叫做 GIL(全局解释锁)的东西,会阻止在程序中同时执行两个线程。一些人非常不喜欢它,但也有一些人喜欢它。目前有一些解决它的方法,不过 Numpy 之类的库大都是通过执行外部 C 语言代码来绕过这种限制。

何时使用线程,何时使用进程?

  • 得益于多核与不存在 GIL,多进程可以加速 CPU 密集型的 Python 程序。
  • 多线程可以很好的处理 IO 任务或涉及外部系统的任务,因为线程可以将不同的工作高效地结合起来。而进程需要对结果进行序列化才能汇聚多个结果,这需要消耗额外的时间。
  • 由于 GIL 的存在,多线程对 CPU 密集的 Python 程序没有什么帮助。

*对于点积等某些运算,Numpy 绕过了 Python 的 GIL 锁,能够并行执行代码。

并行处理示例

Python 的 concurrent.futures 库用起来轻松愉快。你只需要简单的将函数、待处理的对象列表和并发的数量传给它即可。在下面几节中,我会以几种实验来演示何时使用线程何时使用进程。

def multithreading(func, args, 
                   workers):
    with ThreadPoolExecutor(workers) as ex:
        res = ex.map(func, args)
    return list(res)

def multiprocessing(func, args, 
                    workers):
    with ProcessPoolExecutor(work) as ex:
        res = ex.map(func, args)
    return list(res)

API 调用

对于 API 调用,多线程明显比串行处理与多进程速度要快很多。

def download(url):
    try:
        resp = urlopen(url)
    except Exception as e:
        print ('ERROR: %s' % e)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2 个线程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最后

不知道你们用的什么环境,我一般都是用的Python3.6环境和pycharm解释器,没有软件,或者没有资料,没人解答问题,都可以免费领取(包括今天的代码),过几天我还会做个视频教程出来,有需要也可以领取~

给大家准备的学习资料包括但不限于:

Python 环境、pycharm编辑器/永久激活/翻译插件

python 零基础视频教程

Python 界面开发实战教程

Python 爬虫实战教程

Python 数据分析实战教程

python 游戏开发实战教程

Python 电子书100本

Python 学习路线规划

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

e_16,color_FFFFFF,t_70)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值