多进程python_python -- 多进程
python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。
Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其他所有事情。
1.Process
创建进程的类:Process([group [, target [, name [, args [, kwargs]]]]]),target表示调用对象,args表示调用对象的位置参数元组。kwargs表示调用对象的字典。name为别名。group实质上不使用。
方法:is_alive()、join([timeout])、run()、start()、terminate()。其中,Process以start()启动某个进程。
属性:authkey、daemon(要通过start()设置)、exitcode(进程在运行时为None、如果为–N,表示被信号N结束)、name、pid。其中daemon是父进程终止后自动终止,且自己不能产生新进程,必须在start()之前设置。
(1)创建多进程
1 #!/usr/bin/env python
2 #-*- coding: utf-8 -*-
3
4 from multiprocessing importProcess5 importtime6
7
8 deff(name):9 time.sleep(1)10 print("hello", name)11
12 if __name__ == '__main__':13 p1 = Process(target=f, args=['Bob1', ]) #target是创建的进程要执行的函数,args是传递给该函数的参数14 p2 = Process(target=f, args=['Bob2', ]) #这里进程p*的父进程是当前脚本,脚本的父进程是执行环境(eg:pycharm)15 p1.start()16 p2.start()17 p1.join()18 p2.join()19 time.sleep(1)20 print("----main process over----")
执行结果
hello Bob2
hello Bob1----main process over----
2、LOCK
当多个进程需要访问共享资源的时候,LOCK可以用来避免访问的冲突
1 #!/usr/bin/env python
2 #-*- coding: utf-8 -*-
3
4 '''
5 进程同步是说的进程一起执行6 '''
7 from multiprocessing importProcess,Lock8
9 deff(lock,i):10 lock.acquire()11 try:12 print('hello world',i)13 finally:14 lock.release()15
16 if __name__ == '__main__':17 lock =Lock()18
19 for num in range(10):20 Process(target=f,args=(lock,num)).start()
执行结果
hello world 0
hello world3hello world2hello world6hello world5hello world1hello world4hello world7hello world9hello world8
3、Queue、Pipe、Manager
分别利用Queue、Pipe、Manager实现进程间通信
(1)Queue
Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。put方法用以插入数据到队列中,put方法还有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间。如果超时,会抛出Queue.Full异常。如果blocked为False,但该Queue已满,会立即抛出Queue.Full异常。
get方法可以从队列读取并且删除一个元素。同样,get方法有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,会抛出Queue.Empty异常。如果blocked为False,有两种情况存在,如果Queue有一个值可用,则立即返回该值,否则,如果队列为空,则立即抛出Queue.Empty异常。
(2) Pipe
Pipe方法返回(conn1, conn2)代表一个管道的两个端。Pipe方法有duplex参数,如果duplex参数为True(默认值),那么这个管道是全双工模式,也就是说conn1和conn2均可收发。duplex为False,conn1只负责接受消息,conn2只负责发送消息。
send和recv方法分别是发送和接受消息的方法。例如,在全双工模式下,可以调用conn1.send发送消息,conn1.recv接收消息。如果没有消息可接收,recv方法会一直阻塞。如果管道已经被关闭,那么recv方法会抛出EOFError。
(3) Manager
Manager()支持:list、dict、Namespace、Lock、Rlock、Semaphore、 BoundedSemaphore、Condition、Event、Barrier、Queue、Value、Array 其中常用的就list、dict。 注意:其中的list、dict都要通过Manager() 实现。
#!/usr/bin/env python#-*- coding: utf-8 -*-
'''进程之间是不能直接通信的,需要第三方作为通信媒介'''
'''以下是Queue实现数据传递代码'''
from multiprocessing importProcess,Queuedeff1(q):
q.put([22,'root','hello'])deff2(q):
q.put([23,'admin','hello'])'''以下是Pipe实现数据传递代码'''
from multiprocessing importProcess,Pipedeff3(conn):
conn.send([23,'admin1','hello'])deff4(conn):
conn.send([24, 'root', 'hello'])'''以下是Manager实现数据共享代码'''
from multiprocessing importProcess,Managerdeff(d,l,n):
d[n]=n
d['name'] = 'root'l.append(n)print(l)#以下是主程序
if __name__ == '__main__':print('''\033[42;1m 利用Queue实现进程间的通信 \033[0m''')'''这里的进程间通信是在同一父进程下不同子进程间的通信,因为队列q是在父进程实例化并
传递到每个子进程中。(当然可以在一个第三方文件里面创建一个队列,其余文件来调用是可以的)'''q= Queue() #生成一个第三方队列,用来存放子进程put的值
#这里的Queue是在queue.Queue的基础上,封装了能多进程访问
pq1 = Process(target=f1,args=(q,))
pq2= Process(target=f2,args=(q,)) #要把队列对象q当参数传递给各个子进程
pq1.start()
pq2.start()print('from parent 1:',q.get())print('from parent 2:',q.get())print('''\n\033[43;1m 利用Pipe实现进程间的通信 \033[0m''')
parent_conn,child_conn=Pipe()
pp1= Process(target=f3,args=(child_conn,))
pp2= Process(target=f4,args=(child_conn,))
pp1.start()
pp2.start()print('parent data from pp1:', parent_conn.recv())print('parent data from pp2:', parent_conn.recv())
parent_conn.close()#这个在子进程或父进程关闭都可以
print('''\n\033[43;1m 利用Manager实现进程间的数据共享 \033[0m''')'''这里Manager()支持:list、dict、Namespace、Lock、Rlock、Semaphore、
BoundedSemaphore、Condition、Event、Barrier、Queue、Value、Array
其中常用的就list、dict。
注意:其中的list、dict都要通过Manager() 实现'''
#manager = Manager() #注意这样后面需要关闭,用with...as...语句更方便
with Manager() as manager:
d=manager.dict()#l = manager.list() #这样生成空列表
l = manager.list(range(5))
process_list=[]for i in range(10):
p= Process(target=f,args=(d,l,i))
p.start()
process_list.append(p)for res inprocess_list:
res.join()print("执行结束l:",l)print("执行结束d:",d)
4、POOL
在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间。当被操作对象数目不大时,可以直接利用multiprocessing中的Process动态成生多个进程,十几个还好,但如果是上百个,上千个目标,手动的去限制进程数量却又太过繁琐,此时可以发挥进程池的功效。
Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来它。
函数解释:
apply_async(func[, args[, kwds[, callback]]]) 它是非阻塞,apply(func[, args[, kwds]])是阻塞的(理解区别,看例1例2结果区别)
close() 关闭pool,使其不在接受新的任务。
terminate() 结束工作进程,不在处理未完成的任务。
join() 主进程阻塞,等待子进程的退出, join方法要在close或terminate之后使用。
1 #!/usr/bin/env python
2 #-*- coding: utf-8 -*-
3
4 '''
5 进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有6 可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。7
8 进程池方法:9 apply: 同步10 apply_async: 异步11 '''
12 from multiprocessing importProcess,Pool,freeze_support13 importtime14
15 defFoo(i):16 time.sleep(1)17 return i,i+100
18
19 defBar(arg):20 #print('arg:',arg)
21 data.append(arg)22 print('--> exec done [%s]: %s' % (arg[0],arg[1]))23
24 if __name__ == '__main__':25 freeze_support() #要导入,在win下必须有它,不然会报错。linux下不用
26
27 pool = Pool(3) #生成一个有5个进程序列的进程池实例
28 data =[]29 for i in range(10):30 #func为进程每次执行的函数,args是参数,callback是执行完func后执行的函数,
31 #并且callback会自动接收func的返回值作为函数参数。Foo是子进程执行的函数,callback是在
32 #父进程执行的函数,所以这里说明是子进程把执行结果返回给父进程里面的函数
33 pool.apply_async(func=Foo,args=(i,),callback=Bar)34 #pool.apply(func=Foo,args=(i,)) #进程同步,没啥用
35
36 print("end")37 pool.close()38 pool.join() #这里表示进程池中进程执行完毕后再关闭,若注释,那么程序直接关闭
39 #注意:这里是先close,再join
40 print('全局变量data:',data)
执行结果
end--> exec done [0]: 100
--> exec done [1]: 101
--> exec done [2]: 102
--> exec done [3]: 103
--> exec done [4]: 104
--> exec done [5]: 105
--> exec done [7]: 107
--> exec done [6]: 106
--> exec done [8]: 108
--> exec done [9]: 109全局变量data: [(0,100), (1, 101), (2, 102), (3, 103), (4, 104), (5, 105), (7, 107), (6, 106), (8, 108), (9, 109)]
5、Semaphore
Semaphore用来控制对共享资源的访问数量,例如池的最大连接数。
1 #!/usr/bin/env python
2 #-*- coding:utf8 -*-
3
4 importmultiprocessing5 importtime6
7
8 defrun(s, i):9 s.acquire()10 print(multiprocessing.current_process().name + "acquire");11 time.sleep(i)12 print(multiprocessing.current_process().name + "release\n");13 s.release()14
15
16 if __name__ == "__main__":17 s = multiprocessing.Semaphore(2) #最多允许3个进程同时运行
18
19 process_list =[]20 for i in range(3):21 p = multiprocessing.Process(target=run, args=(s, i * 2))22 p.start()23 process_list.append(p)24
25 for process inprocess_list:26 process.join()27
28 print('\033[31;1m 全部结束 \033[0m')
执行结果
Process-1acquire
Process-1release
Process-3acquire
Process-2acquire
Process-2release
Process-3release
全部结束
6、Event
用Event实现进程同步
1 #!/usr/bin/env python
2 #-*- coding:utf8 -*-
3
4 importmultiprocessing5 importtime6
7
8 defwait_for_event(e):9 print("wait_for_event: starting")10 e.wait()11 print("wairt_for_event: e.is_set()->" +str(e.is_set()))12
13
14 defwait_for_event_timeout(e, t):15 print("wait_for_event_timeout:starting")16 e.wait(t)17 print("wait_for_event_timeout:e.is_set->" +str(e.is_set()))18
19
20 if __name__ == "__main__":21 e =multiprocessing.Event()22 w1 = multiprocessing.Process(name="block",23 target=wait_for_event,24 args=(e,))25
26 w2 = multiprocessing.Process(name="non-block",27 target=wait_for_event_timeout,28 args=(e, 2))29 w1.start()30 w2.start()31
32 time.sleep(3)33
34 e.set()35 print("main: event is set")
执行结果
wait_for_event: starting
wait_for_event_timeout:starting
wait_for_event_timeout:e.is_set->False
wairt_for_event: e.is_set()->True
main: eventis set
多进程python_python -- 多进程相关推荐
- pyqt5多进程 python_Python 多进程大全
Python 多线程 阅读本文需要4分钟 1 Python 多线程 多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸 ...
- python多进程_python多进程
上一期我们讲了python中多线程的使用,忘记的小伙伴请戳链接复习,https://zhuanlan.zhihu.com/p/262638052. 还记得我们说到,多线程并不是真正的并发,只是充分利用 ...
- multiprocessing python_Python多进程运行——Multiprocessing基础教程1
多进程是什么 多进程指的是操作系统同时支持多个处理器的能力.在支持多任务操作系统中,一个应用程序会被分解成多个独立运行的较小的程序.操作系统会将这些线程分配到多核处理器,以提升系统性能. 为什么需要多 ...
- python多进程_Python多进程实践
本文重点探究以下几个内容: 创建进程Process 进程间数据传递Queue/Pipe/Value/Array/Manager 进程池Pool 创建进程Process 创建进程方式如下: 可以看出,P ...
- python 多进程 requests_python多进程(二)
之前实现的数据共享的方式只有两种结构Value和Array.Python中提供了强大的Manager专门用来做数据共享的,Manager是进程间数据共享的高级接口. Manager()返回的manag ...
- php 自带多进程,php多进程实现
php多进程实现 PHP有一组进程控制函数(编译时需要–enable-pcntl与posix扩展),使得php能在nginx系统中实现跟c一样的创建子进程.使用exec函数执行程序.处理信号等功能. ...
- python 彻底解读多线程与多进程_python 多进程与多线程浅析
python多线程是伪多线程,同时间最多只有一个线程在执行,但这样并不代码python的多线程没有作用,对于IO密集型的系统,python的多线程还是能极大的提升性能- 关于python伪多线程可以去 ...
- linux 多线程 多进程 利用率,多进程与多线程的深度比较
嵌入式Linux中文站,关于多进程和多线程,教科书上最经典的一句话是"进程是资源分配的最小单位,线程是CPU调度的最小单位".这句话应付考试基本上够了,但如果在工作中遇到类似的选择 ...
- php apache 多进程,php多进程 防止出现僵尸进程 如何 使 apache 成为 僵尸进程
php pcntl 僵尸进程怎么产生的一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是使进程退 ...
最新文章
- c++ 宽搜(倒水)
- Batch Normalization原理及pytorch的nn.BatchNorm2d函数
- BGP策略路由的实现
- 相机内参中cx cy_Opencv中的两种去畸变函数
- VSTO学习笔记(四)从SharePoint 2010中下载文件
- 使用ETags减少Web应用带宽和负载
- chart.js 饼图显示百分比_Excel制作华夫饼图,其实很简单
- python利器-python利器去广告版
- 从设计心理学理解交互设计的原则
- 二进制的加减乘除实现
- qnx slm7.1(程序员开发手册-翻译)
- Fiddler环境配置/代理设置:电脑端/移动端/模拟器
- 解决video更多选项按钮点击无反应以及操控video标签的控制按钮
- JAXWS CXF WSDL first + MyEclipse + Maven Byron自學視頻03
- 《APUE》在Ubuntu上使用apue.h
- linux下脚本录制工具——script和scriptreplay
- Centos开机启动项
- Java百度鹰眼轨迹批量上传
- java jtable组件_java中jtable组件详解实例
- 比较好的python线上培训班
热门文章
- IDEA不愧为神器,结合Groovy脚本,简直无敌!
- 【redis】redis简介及基本数据结构的操作
- 帝国cms7.5多终端刷新单条内容信息时不起作用的解决方法
- pytorch kl散度学习笔记
- libtorch 调用pytorch模型
- Visual Studio 调试(Dubug)模式下的“未定义标识符”
- elasticsearch(7)聚合统计-分组聚合
- Django 无法加载静态文件(js,css,image)解决办法
- Caffe学习系列(8):solver优化方法
- 生成tfreocrds