A. python的多进程模块multiprocessing
众所周知,Python中不存在真正的多线程,Python中的多线程是一个并发过程。如果想要并行的执行程序,充分的利用cpu资源(cpu核心),还是需要使用多进程解决的。其中multiprocessing模块应该是Python中最常用的多进程模块了。
基本上multiprocessing这个模块和threading这个模块用法是相同的,也是可以通过函数和类创建进程。
上述案例基本上就是笔者搬用了上篇文章多线程的案例,可见其使用的相似之处。导入multiprocessing后实例化Process就可以创建一个进程,参数的话也是和多线程一样,target放置进程执行函数,args存放该函数的参数。
使用类来创建进程也是需要先继承multiprocessing.Process并且实现其init方法。
Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求。
但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程。
需要注意的是,在调用join方法阻塞进程前,需要先调用close方法,,否则程序会出错。
在上述案例中,提到了非阻塞,当把创建进程的方法换为pool.apply(func, (msg,))时,就会阻塞进程,出现下面的状况。
在multiprocessing模块中还存在Queue对象,这是一个进程的安全队列,近似queue.Queue。队列一般也是需要配合多线程或者多进程使用。
下列案例是一个使用进程队列实现的生产者消费者模式。
multiprocessing支持两种进程间的通信,其中一种便是上述案例的队列,另一种则称作管道。在官方文档的描述中,multiprocessing中的队列是基于管道实现的,并且拥有更高的读写效率。
管道可以理解为进程间的通道,使用Pipe([plex])创建,并返回一个元组(conn1,conn2)。如果plex被置为True(默认值),那么该管道是双向的,如果plex被置为False,那么该管道是单向的,即conn1只能用于接收消息,而conn2仅能用于发送消息。
其中conn1、conn2表示管道两端的连接对象,每个连接对象都有send()和recv()方法。send和recv方法分别是发送和接受消息的方法。例如,可以调用conn1.send发送消息,conn1.recv接收消息。如果没有消息可接收,recv方法会一直阻塞。如果管道已经被关闭,那么recv方法会抛出EOFError。
关于multiprocessing模块其实还有很多实用的类和方法,由于篇幅有限(懒),笔者就先写到这里。该模块其实用起来很像threading模块,像锁对象和守护线程(进程)等multiprocessing模块也是有的,使用方法也近乎相同。
如果想要更加详细的了解multiprocessing模块,请参考官方文档。
B. 有哪些好用的Python库
Python作为一门胶水语言,第三方库众多,下面我简单介绍几个好用的Python库:
tensorflow
这是谷歌非常着名的一个开源机器学习框架,在业界非常受欢迎,可以灵活、快速的构建大规模机器学习应用(如神经网络等),性能和可移植性都非常不错,支持GPU并行计算,如果你对机器学习比较感兴趣,也想深入了解一下的话,可以学习一下这个框架,非常不错:
pandas
如果你对数据分析比较感兴趣,那么pandas就是一个非常不错的选择,专门为数据分析而建,内置的函数和方法可以快速处理Excel,CSV等文件,而且提供了实时分析功能,代码量更少,使用起来也更方便,对于数据处理来说,是一个非常不错的分析工具:
matplotlib
这是Python的一个数据可视化库,可以快速制作我们常见的图表,如柱状图、饼状图、散点图等,当然,也不仅仅限于这些,还有很多,如果你想画出更多美丽的图表,可以考虑学习一下这个库,非常值得学习,当然,seaborn,pyecharts等这些可视化库也非常不错:
tushare
如果你对金融财经比较感兴趣,想快速获取股票等行情数据,也不想编写复杂的处理代码,那么tushare就是一个非常不错的选择,自动整合了国内大部分金融财经数据,完成了数据从采集、清洗和存储的全过程,只需简单的几行代码就可以实时快速获取到你所想要的数据,免费且开源:
PyQt
这是Python的一个GUI开发库,如果你想快速创建一个桌面GUI程序,想直接拖拽控件布局界面的话,那么PyQt就是一个非常不错的选择,基于Qt的QtDesigner设计工具,你可以直接拖拽Qt大量的控件快速构建出你自己的桌面应用,简单而又快捷:
Kivy
如果你想利用Python开发一个安卓应用,那么kivy就是一个非常不错的选择,这是Python的一个开源、跨平台的GUI库,只需要编写一套代码,即可运行在大部分桌面及移动平台上,包括winsows,linux,ios,android等,非常不错:
scrapy
这是Python的一个爬虫框架,在也就非常受欢迎,如果你想快速的定制自己的爬虫程序,又不想重复的造轮子的话,可以学习一下这个库,只需要添加少量的代码,就可启动属于自己的一个爬虫应用,非常方便:
django
这是一个流行的PythonWeb框架,如果你想快速构建一个自己的web应用,那么这个框架就非常值得学习,成熟稳重,基于MVC模式,使用起来非常方便,当然,也有轻量级的web框架,如flask,tornado等,也都非常不错:
pygame
如果你想快速开发一个小型游戏,又不想低级语言的束缚,可以考虑学习一下这个库,非常简单,只需要少量的代码便可构建一个游戏应用,当然,它也是一个非常不错的GUI库,对于桌面开发来说,也是一个不错的选择:
you-get
这是Python的一个视频、音频下载库,如果你想免费快速下载优派卜酷、B站、腾讯等网站的视频,安装这个库后,只尘竖穗需要简单的一行命令就可直接下载,非常方便,纤哗而且还可以在线观看,查看视频文件格式及清晰度等,当然,图片也可直接下载:
就介绍这10个不错的Python库吧,对于日常学习开发来说,非常不错,当然,还有许多其他好用的Python库,这个可以到网上搜索一下,非常多,也欢迎大家留言补充。
C. python实现多线程并发执行
由于停服维护的需求(服务越来越多的原因),此前编写的shell脚本执行速度缓慢(for循环,这就会很慢),为提高执行速度,参考很多资料,完成此脚本,实现并发执行机制.(当然这是测试脚本,有需要的同学,拿去改ba改ba,应该就可以用了)
此处脚本参考了 https://www.jb51.net/article/86053.htm
D. python并发编程-线程(threading模块)
multiprocess模块 的完全模仿了threading模块的接口,二者在使用层戚州面,有很大的相似性,因而不再详细介绍, 相关知识点可以看这里
1.谁的开启速度快
3.同一进程内的线程共享该进程的数据?
主线程等待高亏蔽子空激线程结束
E. python并发编程-队列介绍
进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道(不推荐使用),这两种方式都是使用消息传递的
创建队列的类(底层就是以管道和锁定的方式实现) :
参数介绍:
方法介绍:
主要方法:
其他方法(了解):
F. python并发编程-Gevent包介绍
Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或中坦举异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。信雀
遇到IO阻塞时会自动切换任务
上例gevent.sleep(2)模拟的是gevent可以识别的io阻塞,
而time.sleep(2)或其他的阻塞,gevent是不能直接识别的需要用下面一行代码,打补丁,就可以识别了
from gevent import monkey;monkey.patch_all()必须放到被打补丁者的前面,如time,socket模块之前
我们可以用threading.current_thread().getName()来查看每个g1和g2,查看的结果为DummyThread-n,即假卖碧线程
通过gevent实现单线程下的socket并发(from gevent import monkey;monkey.patch_all()一定要放到导入socket模块之前,否则gevent无法识别socket的阻塞)
服务端
客户端
多线程并发多个客户端
G. Python中级精华-并发之启动和停止线程
为了让代码能够并发执行,向创建线程并在核实的时候销毁它。
由于目的比较单纯,只是讲解基础的线程创建方法,所以可以直接使用threading库中的Thread类来实例化一个线程对象。
例子,用户输入两个数字,并且求其两个数字的四则运算的结果:
除了以上的一些功能以外,在python线程
中没有其他的诸如给线程发信号、设置线程调度属性、执行任何其他高级操作的功能了,如果需要这些功能,就需要手工编写了。
另外,需要注意的是,由于GIL(全局解释器锁)的存在,限制了在python解释器当中只允许运行一个线程。基于这个原因,不停该使用python线程来处理计算密集型的任务,因为在这种任务重我们希望在多个CPU核心上实现并行处理。Python线程更适合于IO处理以及设计阻塞操作的并发执行任务(即等待IO响应或等待数据库取出结果等)。
如何判断线程是否已经启动?
目的:我们加载了一个线程,但是想要知道这个线程什么时候才会开始运行?
方法:
线程的核心特征我认为就是不确定性,因为其什么时候开始运行,什么时候被打断,什么时候恢复执行,这不是程序员能够控制的,而是有系统调度
来完成的。如果遇到像某个线程的运行依托于其他某个线程运行到某个状态时该线程才能开始运行,那么这就是线程同步
问题,同样这个问题非常棘手。要解决这类问题我们要借助threading中的Event对象。
Event其实和条件标记类似,匀速线程
等待某个时间发生。初始状态时事件被设置成0。如果事件没有被设置而线程正在等待该事件,那么线程就会被阻塞,直到事件被设置位置,当有线程设置了这个事件之后,那么就会唤醒正在等待事件的线程,如果线程等待的事件已经设置了,那么线程会继续执行。
一个例子:
如上能够确定的是,主线程会在线程t运行结束时再运行。
H. python多线程延迟并发
python多线程延迟并发的解决方法如下:
1.python之中多线程的特点,实际上是将执行耗时长的任务放在前台,耗时短的任务放在后台,当处理器有空闲时或者是后台任务主动调用时就会将其拿到前台来执行,而在这个过程之中实际上每次还是执行的一个线程。
2.python多线程延迟并发指的则是当前python程序内有多个程序,也就是任务同时处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。
3.python多线程延迟并发的好处就在于可以更加合理的去调配资源,因为多线程是使用CPU的多核处理器去完成任务的。而并发则是在同一处理器上完成任务,多线程实现并发的话就可以提高运行速度并且减少内存占用。
I. python并发编程-进程池
在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间。多进程是实现并发的手段之一,需要注意的问题是:
例如当被操作对象数目不大时,可以直接利用multiprocessing中的Process动态成生多个进程,十几个还好,但如果是上百个,上千个。。。手动的去限制进程数量却又太过繁琐,此时可以发挥进程池的功效。
我们就可以通过维护一个进程池来控制进程数目,比如httpd的进程模式,规定最小进程数和最大进程数..
ps: 对于远程过程调用的高级应用程序而言,应该使用进程池,Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,就重用进程池中的进程。
创建进程池的类:如果指定numprocess为3,则进程池会从无到有创建三个进程,然后自始至终使用这三个进程去执行所有任务,不会开启其他进程
参数介绍:
方法介绍:
主要方法:
其他方法(了解部分)
应用:
发现:并发开启多个客户端,服务端同一时间只有3个不同的pid,干掉一个客户端,另外一个客户端才会进来,被3个进程之一处理
回调函数:
需要回调函数的场景:进程池中任何一个任务一旦处理完了,就立即告知主进程:我好了额,你可以处理我的结果了。主进程则调用一个函数去处理该结果,该函数即回调函数
我们可以把耗时间(阻塞)的任务放到进程池中,然后指定回调函数(主进程负责执行),这样主进程在执行回调函数时就省去了I/O的过程,直接拿到的是任务的结果。
如果在主进程中等待进程池中所有任务都执行完毕后,再统一处理结果,则无需回调函数