今天我来介绍一下Python多进程多线程,首先简单介绍一下什么是进程和线程。
何为进程?何为线程?
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
线程,有时被称为轻量进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。
相信大家都看明白了,因为多线程多进程都能够充分利用CPU资源,多线程比单线程效率高,多进程比单进程效率高,我们还是用事实说话,下面来进行测试。
我们首先来看一下CPU占用情况,都说多线程可以充分利用CPU,我就来验证一下看看。
我的CPU是4个核心,并没有占用到100%,所以多线程可以充分利用CPU资源显然是不可能的!为什么会这样?因为Python里面有一个传说中的超级大锁——GIL,它不允许线程的并发(一个时间只有一个线程)。既然如此,那么问题来了,都和单线程差不多了,为何还要有这个多线程?它有何用?这个多线程确实有用,只不过不能用在这种纯计算的程序,而是用在当IO请求过多,线程会时不时的因为IO请求被阻塞的情况下,假设我有四个线程(t1,t2,t3,t4)当t1先运行,运行一半需要处理一个IO请求,t1就由运行状态变为阻塞状态,t1的GIL锁被释放,此时此刻,假设(为什么是假设?因为当时t2,t3,t4都有可能获得GIL锁)t2获得GIL锁,t2由等待状态变为就绪状态,然后就开始运行,就这样不停的交替,形成了类似并发的情况,实际上这个就是一个伪并发,所以在IO密集型操作的程序(爬虫,文件读写,操作数据库……)中,使用这个多线程没有问题,不会导致数据的写入错误,就好比爬取网页数据数据到文件中,结果如下图所示。(源码就不要想了,毕竟是爬磁力链接的,但是如果你加了群(群号见文末)私聊我问我要那我还是可以考虑给,这里给怕被和谐
)
还有一个问题,Python写的计算密集型程序如何充分利用CPU资源?有两种办法,一种是用C语言写函数,Python调用C语言链接库,这个太难(毕竟会C语言的Python程序员太少了),我来讲第二种方法,使用多进程(multiprocessing库)。
首先,多进程是不是真的能够充分利用CPU资源呢?继续使用上面那个无限死循环函数测试,测试代码和结果如图所示。
下面我们来看看效率是不是真的提高了,测试代码和结果如图所示
最后得出结论,如果是IO密集型程序使用多线程没毛病,计算密集型程序建议使用多进程。
为什么我会写这篇文章,是因为最近群里有人让我写一篇关于线程进程的文章,所以我就先满足他的需求,大家进了群也可以提出类似的需求,但是一定要记得排队,不要同时给我提太多需求,不然我也会忘!还有就是基础语法我不做讲解,那种东西官方文档绰绰有余,如果让我讲文件操作啥的是完全可以的。
本文分享自 Python机器学习算法说书人 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!