L'éditeur suivant vous apportera une compréhension approfondie de la programmation multi-processus Python. L'éditeur le trouve plutôt bon, je vais donc le partager avec vous maintenant et le donner comme référence pour tout le monde. Suivons l'éditeur pour y jeter un œil
1. Contexte de la programmation multi-processus Python
Le plus grand avantage du multi-processus en Python est Pour en tirer pleinement parti, les ressources CPU multicœurs ne sont pas comme le multithreading en Python, qui est soumis aux restrictions GIL et ne peut être alloué qu'au CPU. Dans le multi-processus de Python, cela convient à toutes les occasions. le multi-threading peut être utilisé, donc fondamentalement, vous pouvez utiliser plusieurs processus.
Lors de la programmation multi-processus, cela est en fait similaire au multi-threading. Dans le package multi-threading, il existe une classe de thread Thread, dans laquelle il existe trois méthodes pour créer un thread et démarrer le. thread En fait, en multi-thread, dans la programmation de processus, il existe une classe de processus Process, qui peut également être utilisée en utilisant la méthode centralisée ; en multi-thread, les données en mémoire peuvent être partagées directement, comme des listes, etc. , mais dans les processus multi-processus, les données de la mémoire ne peuvent pas être partagées, il faut donc utiliser une structure de données distincte pour traiter les données partagées ; dans les processus multi-threads, le partage des données doit garantir l'exactitude des données, il faut donc faire quelque chose, mais dans. multi-processus, les verrous doivent rarement être pris en compte, car les informations de mémoire du processus ne sont pas partagées. Les données interactives entre les processus doivent passer par une structure de données spéciale, le contenu principal est le suivant :
2. La classe multi-processus Process
La classe multi-processus Process et la classe multi-thread Thread ont des méthodes similaires. Les interfaces des deux sont fondamentalement les mêmes. Voir ci-dessous pour plus de détails Code :
#!/usr/bin/env python from multiprocessing import Process import os import time def func(name): print 'start a process' time.sleep(3) print 'the process parent id :',os.getppid() print 'the process id is :',os.getpid() if __name__ =='__main__': processes = [] for i in range(2): p = Process(target=func,args=(i,)) processes.append(p) for i in processes: i.start() print 'start all process' for i in processes: i.join() #pass print 'all sub process is done!'
Comme vous pouvez le voir dans l'exemple ci-dessus, les interfaces API multi-processus et multi-thread sont les mêmes. Le processus de création s'affiche, puis effectuez le démarrage pour commencer à s'exécuter, puis rejoignez et attendez la fin du processus.
Dans la fonction qui doit être exécutée, l'identifiant et le pid du processus sont imprimés, afin que vous puissiez voir les numéros d'identification du processus parent et du processus enfant. Sous Linux, les processus sont principalement dupliqués. Lors de la création d'un processus, les numéros d'identification du processus parent et du processus enfant peuvent être interrogés, mais l'ID du thread est introuvable en multi-threading. L'effet d'exécution est le suivant :
start all process start a process start a process the process parent id : 8036 the process parent id : 8036 the process id is : 8037 the process id is : 8038 all sub process is done!
├─sshd(1508)─┬─sshd(2259)───bash(2261)───python(7520)─┬─python(7521) │ │ ├─python(7522) │ │ ├─python(7523) │ │ ├─python(7524) │ │ ├─python(7525) │ │ ├─python(7526) │ │ ├─python(7527) │ │ ├─python(7528) │ │ ├─python(7529) │ │ ├─python(7530) │ │ ├─python(7531) │ │ └─python(7532)
#!/usr/bin/env python import multiprocessing class MyProcess(multiprocessing.Process): def __init__(self,name,func,args): super(MyProcess,self).__init__() self.name = name self.func = func self.args = args self.res = '' def run(self): self.res = self.func(*self.args) print self.name print self.res return (self.res,'kel') def func(name): print 'start process...' return name.upper() if __name__ == '__main__': processes = [] result = [] for i in range(3): p = MyProcess('process',func,('kel',)) processes.append(p) for i in processes: i.start() for i in processes: i.join() for i in processes: result.append(i.res) for i in result: print i
3. File d'attente d'interaction inter-processus
Lors de l'interaction entre les processus, vous pouvez d'abord utiliser la même structure de file d'attente en multi-threading. en multi-processus, vous devez utiliser la Queue en multiprocessing. Le code est le suivant :#!/usr/bin/env python import multiprocessing class MyProcess(multiprocessing.Process): def __init__(self,name,func,args): super(MyProcess,self).__init__() self.name = name self.func = func self.args = args self.res = '' def run(self): self.res = self.func(*self.args) def func(name,q): print 'start process...' q.put(name.upper()) if __name__ == '__main__': processes = [] q = multiprocessing.Queue() for i in range(3): p = MyProcess('process',func,('kel',q)) processes.append(p) for i in processes: i.start() for i in processes: i.join() while q.qsize() > 0: print q.get()
4. Interaction entre les processus Pipe
Pipe peut également être utilisé lors de l'échange de données entre processus. Le code est le suivant :
#!/usr/bin/env python import multiprocessing class MyProcess(multiprocessing.Process): def __init__(self,name,func,args): super(MyProcess,self).__init__() self.name = name self.func = func self.args = args self.res = '' def run(self): self.res = self.func(*self.args) def func(name,q): print 'start process...' child_conn.send(name.upper()) if __name__ == '__main__': processes = [] parent_conn,child_conn = multiprocessing.Pipe() for i in range(3): p = MyProcess('process',func,('kel',child_conn)) processes.append(p) for i in processes: i.start() for i in processes: i.join() for i in processes: print parent_conn.recv()
5. Pool de processus pool
En fait, lorsque vous utilisez plusieurs processus, je pense que l'utilisation de pool est la plus pratique en multi-. threading, c'est Il n'y a pas de pool.在使用pool的时候,可以限制每次的进程数,也就是剩余的进程是在排队,而只有在设定的数量的进程在运行,在默认的情况下,进程是cpu的个数,也就是根据multiprocessing.cpu_count()得出的结果。
在poo中,有两个方法,一个是map一个是imap,其实这两方法超级方便,在执行结束之后,可以得到每个进程的返回结果,但是缺点就是每次的时候,只能有一个参数,也就是在执行的函数中,最多是只有一个参数的,否则,需要使用组合参数的方法,代码如下所示:
#!/usr/bin/env python import multiprocessing def func(name): print 'start process' return name.upper() if __name__ == '__main__': p = multiprocessing.Pool(5) print p.map(func,['kel','smile']) for i in p.imap(func,['kel','smile']): print i
在使用map的时候,直接返回的一个是一个list,从而这个list也就是函数执行的结果,而在imap中,返回的是一个由结果组成的迭代器,如果需要使用多个参数的话,那么估计需要*args,从而使用参数args。
在使用apply.async的时候,可以直接使用多个参数,如下所示:
#!/usr/bin/env python import multiprocessing import time def func(name): print 'start process' time.sleep(2) return name.upper() if __name__ == '__main__': results = [] p = multiprocessing.Pool(5) for i in range(7): res = p.apply_async(func,args=('kel',)) results.append(res) for i in results: print i.get(2.1)
在进行得到各个结果的时候,注意使用了一个list来进行append,要不然在得到结果get的时候会阻塞进程,从而将多进程编程了单进程,从而使用了一个list来存放相关的结果,在进行得到get数据的时候,可以设置超时时间,也就是get(timeout=5),这种设置。
总结:
在进行多进程编程的时候,注意进程之间的交互,在执行函数之后,如何得到执行函数的结果,可以使用特殊的数据结构,例如Queue或者Pipe或者其他,在使用pool的时候,可以直接得到结果,map和imap都是直接得到一个list和可迭代对象,而apply_async得到的结果需要用一个list装起来,然后得到每个结果。
以上这篇深入理解python多进程编程就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持PHP中文网。
更多Comprendre la programmation multi-processus en python相关文章请关注PHP中文网!