35、python并发编程之多线程(理论篇)

说白了,多线程就是让一个程序同时干几件事,但得用同一块内存。
其实很简单,就像北京地铁1 3 号线,所有线路用同一套资源,但各干各的活。

先说最重要的,多线程最大的好处是共享内存,不用像进程那样复制数据。
比如去年我们跑的那个项目,处理图片和响应用户请求用两线程,省了大概3 0%的内存开销。
另外一点,线程创建快,去年测试创建1 00个线程比创建进程快了快1 00倍。
还有个细节挺关键的,比如在I/O等待时,线程能切换去干别的活,去年跑网络爬虫的测试里,多线程比单线程快了2 倍。
说实话挺坑的,Python的多线程因为GIL限制,真跑不快多核CPU,但用在I/O密集型任务上还是值得试试。

我一开始也以为线程切换是随机的,后来发现不对,得用thread_yield手动让出CPU,不然跑起来像狗屁不通。
等等,还有个事,子线程如果继承父线程的锁,可能会卡死整个进程,这个点很多人没注意。

最后提醒下,线程间的资源竞争是个大坑,比如一个线程在写文件,另一个线程突然要读,直接崩。

使用Python实现多线程和多处理方法

说白了,Python中的多线程和多处理是实现并行编程的两大法宝,它们能在不同场景下大幅提升程序性能。
其实很简单,但得看具体任务类型。

先说最重要的,多线程适用于I/O密集型任务,比如下载图片。
比如去年我们跑的那个项目,大概3 000量级图片下载,用多线程就快多了。
其实,我一开始也以为CPU密集型也适用,后来发现不对,因为Python有GIL(全局解释器锁),它让同一时间只能一个线程执行,所以在CPU密集型任务中效果不明显。

另外一点,多处理适合CPU密集型任务,如计算平方和。
去年我们有个数据处理的任务,用了多处理,效率提升明显。
等等,还有个事,创建进程比线程开销大,所以任务粒度小的时候,多线程可能更合适。

这个点很多人没注意,多线程时要注意线程安全,比如使用锁来避免竞态条件。
而多处理的话,由于每个进程有独立内存,通信和数据共享需要用特定机制,比如队列。

最后提醒个容易踩的坑,就是选择合适的线程或进程数量。
太多线程或进程反而可能降低效率,因为系统资源有限。
所以,我觉得值得试试根据任务特性动态调整线程或进程数。

一篇文章带你深度解析Python线程和进程

哎哟,哥们,说起Python线程和进程,这可真是个技术活。
我刚接触这玩意儿那会儿,也是一头雾水,现在稍微懂点皮毛了,给你唠唠。

我记得那是在2 01 6 年,我在一家初创公司做后端开发,那时候负责一个数据分析项目。
那个项目得处理海量的数据,得跑好几个数据处理流程,结果就是服务器一直卡在那儿,效率低得要命。

那时候我就想,得,得用用线程,提高效率。
刚开始,我用了Python自带的threading模块,创建了一个线程池,把数据处理任务分配到不同的线程去执行。
结果呢?表面上看是快了点,但实际并没多大提升。
我那时候不懂,还以为是自己代码写得不好,瞎折腾了好久。

后来,我查资料才知道,原来Python有那个GIL(Global Interpreter Lock,全局解释器锁)的存在。
这货就是Python线程的杀手,它保证了同一时刻只有一个线程在执行,所以在多核CPU上,线程并不能真正并行执行。
我这才发现,原来我的线程并没有发挥多大作用。

然后,我又开始研究进程。
我用了multiprocessing模块,通过创建多个进程来并行处理数据。
这回效率确实提高了,但问题又来了。
进程间的通信和数据同步问题让我头疼不已,处理起来特别麻烦。

那时候我就想,这进程和线程,各有各的坑,真是一言难尽啊。
不过,后来我用了一个叫做gevent的库,它基于greenlet,可以自动切换任务,避免了GIL的限制。
这回,我的项目效率提升了不少,而且代码也变得简单易懂。

现在想想,那时候真是浪费了不少时间在踩坑上。
不过,这些经历也让我对Python的线程和进程有了更深入的理解。
总之,如果你也想用Python提升程序运行速度,这俩玩意儿你得好好研究研究。

哦,对了,我还得提醒你一下,这线程和进程,用得好能提升效率,用不好反而会拖后腿。
得根据实际情况来定,别盲目跟风。
比如,如果你的程序是I/O密集型的,比如网络请求、文件读写,那用多线程可能效果会更好;如果是CPU密集型的,比如大量的数学运算,那用多进程可能更合适。

哎,说这么多,都是我亲身经历过的。
希望这能帮到你,兄弟!有啥不懂的,尽管问。