2023年8月2日发(作者:)
Python创建进程的两种⽅式1.多进程由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使⽤多核CPU的资源,在python中⼤部分需要使⽤进程.Python提供了⾮常好的多进程包multiprocessing,只需要定义⼀个函数,Python会完成其他所有事情.借助这个包,可以轻松完成从单进程到并发执⾏的转换.multiprocessing⽀持⼦进程,通信和共享数据,执⾏不同形式的同步,提供process,queue,pipe,lock等组件。multiprocessing包是Python中的多进程管理包.与类似,它可以利⽤s对象来创建⼀个进程.该进程可以运⾏Python程序内部编写的函数.该Process对象与Thread对象的⽤法相同,也有start(),run(),join的⽅法,此外multiprocessing包中也有lock/Event/Semophore/Condition类(这些对象可以像多线程那样,通过参数传递给各个进程),⽤以同步进程,其⽤法与threading包中的同名类⼀致.所以,multiprocessing的很⼤⼀部分与threading使⽤同⼀套API,只不过换到多进程的情境。在使⽤这此共享API的时候,我们要注意以下⼏点:在UNIX平台上,当某个进程终结之后,该进程需要被⽗进程调⽤wait,否则进程成为僵⼫进程。所以,有必要对每个Process对象调⽤join()⽅法(实际上等同于wait).对于多线程来说,由于只有⼀个进程,所以不存在此必要性multiprocessing提供了threading包中没有的IPC(⽐如Pipe和Queue),效率上更⾼。应优先考虑Pipe和Queue,避免使⽤lock/event/semaphore/condition等同步(因为它们占据的不是⽤户进程的资源)多进程应该避免共享资源。在多线程中,⽐较容易使⽤共享资源,⽐如使⽤全局变量或者传递参数。在多进程情况下,由于每个进程有⾃⼰独⽴的内存空间,以以⽅法并不合适。此时可以共享内存和mangaer的⽅法共享资源。但这样做提⾼了程序的复杂度,并因为同步需要⽽降低了程序的效率。ProcessPID中保存有PID,如果进程还没有start(),即PID为None在windows系统下,需要注意的是要想启动⼀个⼦进程,必须加上那句if__name__==“main”,进程相关的要写在这句下⾯.2.实例分析[root@node2 multiprocess]# cat #!/usr/local/python3/bin/python3from multiprocessing import Process #引⽤进程模块import timedef f(name): (1) print('hello',name,())
if __name__=='__main__': p_list=[] for i in range(3): p = Process(target=f, args=('reid',)) #创建⼀个进程对象,再传⼊⼀个函数f为参数 p_(p) () for p in p_list: () print('end')[root@node2 multiprocess]# python3 #程序中有⼀个主进程,三个⼦进程,进程之间是独⽴运⾏的,互不⼲扰hello reid Sun Jun 10 10:13:57 2018hello reid Sun Jun 10 10:13:57 2018hello reid Sun Jun 10 10:13:57 2018end类式调⽤'''遇到问题没⼈解答?⼩编创建了⼀个Python学习交流QQ群:579817333
寻找有志同道合的⼩伙伴,互帮互助,群⾥还有不错的视频学习教程和PDF电⼦书!'''[root@node2 multiprocess]# cat #!/usr/local/python3/bin/python3from multiprocessing import Processimport time
class MyProcess(Process): #继承multiprocessing下的Process def __init__(self): super(MyProcess,self).__init__() #继承⽗类的init⽅法
def run(self): (1) print('hello',,())
#三个进程同时打印,本⾝有值,进程对象下的⼀个属性,进程名,如进程1,进程2等,也可以赋值,在实例化对象时,传⼊⼀个参数
if __name__=='__main__': p_list=[] for i in range(3): p = MyProcess() #进程对象 () #启动 p_(p)
for p in p_list:
print('end')[root@node2 multiprocess]# python3 ello MyProcess-1 Sun Jun 10 11:43:24 2018hello MyProcess-3 Sun Jun 10 11:43:24 2018hello MyProcess-2 Sun Jun 10 11:43:24 2018⽗进程与⼦进程间的关系[root@node2 multiprocess]# cat #!/usr/local/python3/bin/python3from multiprocessing import Processimport osimport timedef info(title): print(title) #传输什么,打印什么 print('module name: ',__name__) #__name__是main print('parent prcess: ',d()) #打印⽗进程号 print('process id: ', ()) #打印进程号
def f(name): info('033[31;1mfunction f033[0m') print('hello',name)
if __name__=='__main__': info('033[32;1mmain process line 033[0m') #传⼊参数,执⾏info函数 (3) p = Process(target=info,args=('bob',)) #创建⼦进程 () ()[root@node2 multiprocess]# python3 process linemodule name: __main__ 主进程parent prcess: 13838process id: 14521 ###bobmodule name: __main__ ⼦进程parent prcess: 14521 ###process id: 145223.进程通信和数据共享分析:线程可以共享数据,进程之间实现通信的⽅法是使⽤pipe和queue(1)、Queue'''遇到问题没⼈解答?⼩编创建了⼀个Python学习交流QQ群:579817333
寻找有志同道合的⼩伙伴,互帮互助,群⾥还有不错的视频学习教程和PDF电⼦书!'''[root@node2 multiprocess]# cat #!/usr/local/python3/bin/python3from multiprocessing import Process,Queuedef f(q): ([42,2,'hello'])
if __name__=='__main__': q = Queue() #进程队列 p_list=[] for i in range(3): p = Process(target=f,args=(q,)) #q作为参数由⽗进程传给⼦进程,因为正确情况下,⽗进程和⼦进程不能通信 p_(p) () print(()) print(()) print(()) for i in p_list: ()[root@node2 multiprocess]# python3 [42, 1, 'hello'][42, 0, 'hello'][42, 2, 'hello']确认def f中的q和p = Process(target=f,args=(q,i))中的q[root@node2 multiprocess]# cat #!/usr/local/python3/bin/python3from multiprocessing import Process,Queuedef f(q): ([42,2,'hello']) print('subprocess q id: ', id(q)) ###id⼀样表⽰是共享的,不⼀样表⽰copy的
if __name__=='__main__': q = Queue() p_list=[] print('main q id: ', id(q)) ###
for i in range(3): p = Process(target=f,args=(q,)) p_(p) () print(()) print(()) print(()) for i in p_list: ()[root@node2 multiprocess]# python3 q id: 142subprocess q id: 142 #windows测试可能不⼀样[42, 2, 'hello']subprocess q id: 142subprocess q id: 142[42, 2, 'hello'][42, 2, 'hello'](2)、Pipe分析:⽗进程处理阻塞状态等待接收,⼦进程进⾏发送数据'''遇到问题没⼈解答?⼩编创建了⼀个Python学习交流QQ群:579817333
寻找有志同道合的⼩伙伴,互帮互助,群⾥还有不错的视频学习教程和PDF电⼦书!'''[root@node2 multiprocess]# cat #!/usr/local/python3/bin/python3from multiprocessing import Process,Pipedef f(conn): ([42,None,'hello']) ()
if __name__=='__main__': parent_conn,child_conn = Pipe() #⽗进程和字进程的通道 p = Process(target=f,args=(child_conn,))
#把⼦进程的通道作为参数传⼊⼦进程,通过函数f可以进⾏send和reveice,⽽且在主进程也有parent conn
() #启动⼀个⼦进程 print(parent_()) #⽗进程在等待接收(阻塞),直到⼦进程执⾏f函数时,有个⼦进程的管道进⾏发送数据,parent_conn可以接收 ()[root@node2 multiprocess]# python3 [42, None, 'hello'](3)、Manager描述: 数据共享[root@node2 multiprocess]# cat #!/usr/local/python3/bin/python3from multiprocessing import Process, Managerdef f(d,l,n): #d是字典,l是列表,n是i⼀个0-9的值 d[n] = '1' #d实际是manager创建的 d['2'] = 2 d[0.25] = None#字典d,当⼀个进程进⼊后,操作后有三个键值对,第⼆个进程进⼊后,d,l是⼀样的,会被覆盖掉,如果把n修改成1就变成三个键值对,#因为第⼀个进程进⼊时,字典是空的,会⾸先创建三个键值对,第⼆个进程进⼊时,会进⾏覆盖,因为字典是共⽤的,d[1] = 1都⼀样,#所以10个进程⾛完后,三个键值对不还是⼀样 (n) #往列表中添加值
if __name__=='__main__': with Manager() as manager: ##manager = manager() d = () #创建⼀个空字典实现进程之间共享
l = (range(5)) #创建⼀个从0到4的列表 p_list = [] for i in range(10): #创建10个进程 p = Process(target=f,args=(d,l,i)) () p_(p) for res in p_list: () print(d) print(l)[root@node2 multiprocess]# python3 {0: '1', '2': 2, 0.25: None, 3: '1', 5: '1', 1: '1', 6: '1', 4: '1', 7: '1', 8: '1', 2: '1', 9: '1'} #三组键值对[0, 1, 2, 3, 4, 0, 3, 5, 6, 1, 4, 7, 8, 2, 9] ##0,1,2,3,4是初始时就有分析:主进程和⼦进程是否⼀致'''遇到问题没⼈解答?⼩编创建了⼀个Python学习交流QQ群:579817333
寻找有志同道合的⼩伙伴,互帮互助,群⾥还有不错的视频学习教程和PDF电⼦书!'''[root@node2 multiprocess]# cat #!/usr/local/python3/bin/python3from multiprocessing import Process, Managerdef f(d,l,n): d[n] = '1' d['2'] = 2 d[0.25] = None (n) print('sub',id(d)) #########
if __name__=='__main__': with Manager() as manager: d = ()
l = (range(5)) p_list = []
print('main',id(d)) ####### for i in range(10): p = Process(target=f,args=(d,l,i)) () p_(p) for res in p_list: () print(d) print(l)
[root@node2 multiprocess]# python3 ##结果windows不⼀样,linux中是⼀样的main 142sub 142sub 142sub 142sub 142sub 142sub 142sub 142sub 142sub 142sub 142{0: '1', '2': 2, 0.25: None, 3: '1', 2: '1', 4: '1', 7: '1', 8: '1', 5: '1', 1: '1', 9: '1', 6: '1'}[0, 1, 2, 3, 4, 0, 3, 2, 4, 7, 8, 1, 5, 6, 9
发布者:admin,转转请注明出处:http://www.yc00.com/news/1690956311a472528.html
评论列表(0条)