小叮当Python并发(三):走近进程与线程之“实战演练”

1..多进程和多线程的选择
计算机常见的处理任务有计算密集型和io密集型。计算密集型需长期占用cpu,在python中常选择多进程处理;io密集型则不需长期占用cpu,在python中常选择多线程处理。
计算密集型
程序系统大部分在做计算、逻辑判断、循环导致cpu占用率很高的情况,称之为计算密集型。例如计算圆周率、对视频进行高清解码等,全靠cpu的运算能力。
io密集型
频繁地进行网络传输、读取硬盘及调用输入输出设备的情况称之为io密集型。这类任务的特点是cpu消耗很少,任务的大部分时间都在等待io操作完成(因为io的速度远远低于cpu和内存的速度)。对于io密集型任务,任务越多,cpu效率越高。常见的大部分任务都是io密集型任务,比如web应用。
(1)计算密集型---选择多进程
在python中,我们常选择多进程来提高对计算密集型任务的执行效率。
step1.首先,我们导入时间模块用来记录程序运行时间以作比较。然后我们导入多进程模块,并定义一个计算密集型函数func( )用来进行测试。为保证计算量足够大我们设置最低循环次数为一千万。
注意:这里跟大家分享个很实用的python中for的用法。
大家可以看到小叮当这里的for循环变量没有用字母,而是用了下划线。这是为什么呢?
这是因为,在python中当使用下划线做for的循环变量时,“_”只作为临时性的名称使用。这样一来,当其他人阅读你的代码时将会知道,你分配了一个特定的名称,但是并不会在后面再次用到该名称。而程序也知道“_”只用来计数,便不会再为开辟存储单元,从而提高了代码的执行效率。
step2.之后我们设置对照组,定义main1()函数,执行两次func函数。并在执行func函数前记录开始时间,在执行后再次记录结束时间。最后输出两者差值便是计算密集型函数func( )的执行时间。
step3.设置试验组,通过定义main2( )函数多进程来执行计算密集型函数func( )函数,并测试其运行时间。思路和step2一样,这里便不再赘述。
注意:1.使用p.join( )等待进程结束后再记录结束时间。
当执行多进程时,由于代码是顺序执行的,若不加上p.join( )这个方法,上图代码会在开启进程后就记录结束时间,而此时进程刚启动,还并未将func( )执行完毕。也就是说我们不用p.join( )方法等待进程结束,我们便无法获得正确的多进程执行函数时间。
注意:2.p.join( ) 的使用位置,需定义全局变量
p.join( )的位置不能在创建进程的for循环内。若在循环内,程序则是分配进程执行func,由于p.join( )的作用,程序会在这一进程执行完后才执行下一个创建的进程。这样虽然是创建了多进程却也是顺次执行与单进程无异。这样便不能发挥出多进程的效率了。但我们在循环外使用p.join( ),而p是在for循环内部定义的。该怎么办?我们可以在for循环前通过global定义p为全局变量,这样便可在for循环外执行p.join( )方法了。
step4.设置程序入口,执行对照组与试验组,测试多进程执行计算密集型任务。
实验结果:从实验结果中,可以明显看出,使用了多进程的试验组main2( )在同样执行两次func( )函数时,效率更高。
实验结论:python中执行计算密集型任务时选择多进程,比不使用多进程效率高。
(2)io密集型---选择多线程
在python中,我们常选择多线程来提高对io密集型任务的执行效率。由于和多进程实验设计思路一样,这里不再赘述细节。
step1.引入相应模块,定义io密集型函数func( )为更好在pycharm解释器中对比实验结果,这里设置为100次。
step2.定义对照组,直接执行io密集型函数fun( )不使用多线程。
step3.定义实验组,使用多线程执行io密集型函数fun( )。
step4.设置程序入口执行测试。
实验结果:从实验结果中,可以明显看出,使用了多线程的试验组main2( )在同样执行两次func( )函数时,效率更高。
实验结论:python中执行io密集型任务时选择多线程,比不使用多线程效率高。2.多线程多进程实现并发服务器
由于设计思路一样,这里以多线程为例,为大家说明。
step1.建立通信客户端。
step2.建立多线程服务器。使每来一个客户服务器都自动创建一个线程为其服务。
(1)创建服务器,与客户端端口9999一致,并设置监听数。
(2)定义通信方法communication,每来一个客户端就创建一个新线程,负责和客户端通信。
(3)设计服务器端的友好显示并创建客户线程。
step3.先启动设计好的服务器。
再启动设计好的客户端,我们可以多运行几次客户端,使之出现多个客户端。
step4.在五个客户端分别输入“我是it小叮当,这个第...个客户端”并回车。
第1个客户端第2个客户端第3个客户端第4个客户端
第5个客户端实验结果:通过服务器结果,我们可以看到,服务器已接受到这5个客户端的信息并记录了其地址信息,实现了我们的实验目的。
以上实验小叮当用的是python3.6和pycharm3.x。大家如果在操作过程中,遇到了什么问题,尽可在评论区留言,小叮当看到后便会及时回复大家的。