python中的多任务-多线程和多进程

多线程和多进程都是实现多任务的一种方式,但是对于很多初学者来说想分清楚他们往往是一件非常头疼的事,首先我们需要了解多任务的概念。

python中的多任务-多线程和多进程

所谓的多任务就是在同一时刻同时做很多事情,比如我们一边使用浏览器上网一边听着网易云音乐歌曲,同时又登录着QQ和微信,这时候至少有3个以上的任务同时运行,当然还有很多后台的程序运行着,只是我们看不到而已。

现在的多核CPU可以说是非常普及了,但即使是以前的单核老电脑同样也是可以运行多任务的,但由于代码的顺序执行特性,单核CPU是怎样执行多任务的呢?

python中的多任务-多线程和多进程

答案就是操作系统使用了时间片轮转的算法让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒……这样反复执行下去。表面上看,每个任务都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像所有任务都在同时执行一样,这种执行方式叫做并发。

python中的多任务-多线程和多进程

python中的多任务-多线程和多进程

如果任务数小于等于cpu核数,即任务真的是一起执行,这种执行方式叫做并行,真正的并行执行多任务只能在多核CPU上实现,但是,由于任务数量远远多于CPU的核心数量,所以,操作系统也会自动把很多任务轮流调度到每个核心上执行。

实际程序开发中会大量使用多任务,如微信在发信息的同时需要接收信息,网易云音乐在下载的同时又需要播放歌曲。python语言中实现多任务的方式有三种:线程,进程和协程,协程会在后面的文章中给大家单独讲解,首先我们来分析一下线程和进程。

python中的多任务-多线程和多进程

如上代码,在main()函数中调用了load()和play()的函数分别用来模拟下载和播放音乐,但由于程序运行的时候只有一个主线程,所以先执行完下载音乐的代码再去执行播放音乐代码,程序的效率非常低。

python中的多任务-多线程和多进程

实际上我们在下载音乐的同时可以播放音乐,python中有一个实现多线程的类Thread,但由于这个类的代码太底层了,一般情况下我们会使用threading这个高级的类,threading其实也是对Thread类的封装,但里面包含了很多强大的功能,同时使用也是非常地方便。

python中的多任务-多线程和多进程

使用多线程完成多任务

python中的多任务-多线程和多进程

运行结果

我们发现下载音乐和播放音乐的代码几乎是同时在进行的,这样程序执行效率会非常高,线程是操作系统能够进行运算调度的最小单位(程序执行流的最小单元)。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。如果把进程比做是一个办公室,则线程是办公室里面工作的一个员工,实际上完成工作的是员工而不是办公室,一个办公室里面配置两个员工的工作效率是要比一个员工高很多的。一个进程至少要有一个线程,就如同一个办公室至少需要配备一个员工,上面的程序实际上有三个线程,运行main函数的父线程,可以想象成是办公室中的老板,另外两个就是执行load和play函数的子线程,就如同是老板招来的员工。

线程间的数据是相互共享的,就如同办公室里面的一台饮水机,办公室所有员工和老板都可以去打水喝,如下代码,load函数和play函数都可以访问到变量song_name里的歌曲名。

python中的多任务-多线程和多进程

接下来我们使用多进程的方式完成同时下载和播放音乐,在Python中,存在一个跨平台的包multiprocessing,通过引入包中的Process类,就可以创建多进程程序了,可以创建一个进程p=Process(target=func,args=(*,)),然后利用p.start()及p.join()来执行就可以了,代码如下:

python中的多任务-多线程和多进程

这时候我们发现运行代码后没有任何输出,主要的原因是进程之间是相互独立的,所以运行后的数据不会在运行的控制台显示。调用完子进程程start()方法后,主进程会马上结束,但子进程仍然会继续运行,如果我们想等待某一个子进程结束后再结束主进程,可以调用子进程的join()方法。

另外,可以用进程池的方式,例如p=Pool(n),然后p.apply_async(func,args),这里可以使用n种不同的参数传入,建立不同的进程。用这种方式时,在调用join()方法前,要先调用close()方法,使得不能再添加新进程。

python中的多任务-多线程和多进程

进程之间的数据是相互独立的,所以不能使用全局变量共享数据,就如同两个完全独立的办公室,在不出办公室的情况下这个办公室的员工是不能喝到另外一个办公室里面饮水机的水的。如果需要数据共享, mutiprocessing包里提供了Queue、Pipe等多种进程间通信的方法。可以直接引入队列Queue类,然后实例化一个对象。则不同的进程可以使用put方法发信息,同时可以使用get方法取信息。

python中的多任务-多线程和多进程

运行效果如下:

python中的多任务-多线程和多进程

最后来说一下两者的优缺点。多进程的优点是稳定性好,一个子进程崩溃了,不会影响主进程以及其余进程。但是缺点是创建进程的代价非常大,因为操作系统要给每个进程分配固定的资源,并且,操作系统对进程的总数会有一定的限制,若进程过多,操作系统调度都会存在问题,会造成假死状态。

多线程优点是效率较高一些,但是致命的缺点是任何一个线程崩溃都可能造成整个进程的崩溃,因为它们共享了进程的内存资源池。 对于任务数来说,无论是多进程或者多线程,都不能太多。因为操作系统在切换任务时,会有一系列的保护现场措施,这要花费相当的系统资源,若任务过多,则大部分资源都被用做干这些了,结果就是所有任务都做不好,所以操作系统会限制进程的数量。 另外,考虑计算密集型及IO密集型应用程序。对于计算密集型,多任务势必造成资源浪费。对于IO密集型,因为IO速度远低于CPU计算速度,所以使用多任务方式可以大大增大程序运行效率。

好了,今天和大家分享的多任务的知识就到这里了,下一篇文章将继续为大家讲解python中实现多任务的第三种方式: 协程。作者是一名热爱编程的老师,熟练掌握c,c++,java,javascript,python,c#,go等热门编程语言,欢迎共同学习交流,发一篇文章真心不容易,喜欢作者的记得关注哦(*^_^*)

https://www.toutiao.com/a6665988558018314759/

猜你喜欢

转载自blog.csdn.net/weixin_42137700/article/details/88368860