Maison  >  Article  >  développement back-end  >  Explication du didacticiel sur le contrôle multi-processus Python (avec exemples)

Explication du didacticiel sur le contrôle multi-processus Python (avec exemples)

不言
不言avant
2018-11-15 14:00:201901parcourir

Cet article vous propose un tutoriel sur le contrôle multi-processus python (avec des exemples). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Introduction au multitraitement

Le multitraitement est un module multi-processus fourni avec Python. Il peut générer des processus en gros lots. L'effet est meilleur lorsque le serveur est un serveur. CPU multicœur, similaire au module de thread. Comparé au multi-threading, le multi-traitement est plus stable et sécurisé en raison de son espace mémoire exclusif lors des opérations par lots en exploitation et en maintenance, le multi-traitement a des scénarios plus applicables

Le package multitraitement fournit à la fois local et local. Les opérations simultanées à distance évitent efficacement d'utiliser des processus enfants au lieu de threads avec des verrous d'interprétation globaux. Par conséquent, le multitraitement peut utiliser efficacement le traitement multicœur

Classe de processus

Dans. multiprocesseur, les processus sont générés par lots via des objets de classe Process et la méthode start() est utilisée pour démarrer le processus

Syntaxe

multiprocessing.Process(group=None,target=None,name=None,args=(),kwargs={},*)

group: 这个参数一般为空,它只是为了兼容threading.Tread
target: 这个参数就是通过run()可调用对象的方法,默认为空,表示没有方法被调用
name: 表示进程名
args: 传给target调用方法的tuple(元组)参数
kwargs: 传给target调用方法的dict(字典)参数

2. Méthodes et objets de la classe Process

run()Cette méthode est le processus en cours d'exécution du processus et peut être utilisé dans les sous-classes Cette méthode est généralement réécrite en

start() pour démarrer le processus. Chaque objet processus doit être appelé par cette méthode.

join([timeout])Attendez la fin du processus avant de continuer. Vous pouvez définir le délai d'attente

. name peut obtenir le nom du processus, plusieurs processus peuvent également avoir le même nom

is_alive()Renvoie si le processus est toujours en vie, Vrai ou Faux, la survie du processus fait référence au début de start() jusqu'à la fin du processus enfant

démonLa marque du processus démon, une valeur booléenne, dans start(), puis définissez cette valeur pour indiquer s'il doit s'exécuter en arrière-plan
Remarque : si l'exécution en arrière-plan est définie, le programme en arrière-plan ne s'exécutera pas et créera ensuite un processus enfant

pidVous pouvez obtenir l'ID du processus

code de sortieLa valeur lorsque le processus enfant se termine. Si le processus n'est pas terminé, la valeur sera None, s'il s'agit d'une valeur négative, indiquant que le processus enfant est terminé

terminate() Terminez le processus. S'il s'agit de Windows, utilisez terminateprocess(). Cette méthode est déjà terminée et terminée. Le processus ne sera pas exécuté

Ce qui suit est un exemple simple :

#-*- coding:utf8 -*- 
import multiprocessing
import time

def work(x):
   time.sleep(1)
   print time.ctime(),'这是子进程[{0}]...'.format(x)

if __name__ == '__main__':
    for i in range(5):
        p = multiprocessing.Process(target=work,args=(i,))
        print '启动进程数:{0}'.format(i)
        p.start()
        p.deamon = True

Explication du didacticiel sur le contrôle multi-processus Python (avec exemples)

Bien sûr, chacun peut également être affiché ID de processus

#-*- coding:utf8 -*- 
import multiprocessing
import time
import os

def work(x):
   time.sleep(1)
   ppid = os.getppid()
   pid  = os.getpid()
   print time.ctime(),'这是子进程[{0},父进程:{1},子进程:{2}]...'.format(x,ppid,pid)

if __name__ == '__main__':
    for i in range(5):
        p = multiprocessing.Process(target=work,args=(i,))
        print '启动进程数:{0}'.format(i)
        p.start()
        p.deamon = True

Explication du didacticiel sur le contrôle multi-processus Python (avec exemples)

Mais en utilisation réelle, il ne suffit pas de terminer le processus en parallèle. Par exemple, il y a 30 tâches. En raison des ressources limitées du serveur, il y a 5 tâches simultanément à chaque fois. Cela implique également la question de savoir comment obtenir 30 tâches. De plus, il est difficile de garantir un temps d'exécution cohérent des tâches de processus simultanées, en particulier des tâches qui nécessitent du temps. Il peut y avoir 5 tâches simultanément, et 3 d'entre elles sont terminées et 2 prendront beaucoup de temps à exécuter. N'attendez pas que ces deux processus soient terminés avant de continuer à exécuter les tâches suivantes. Par conséquent, le contrôle de processus a ici un scénario d'utilisation. Vous pouvez utiliser la méthode Process et certains packages et classes multitraitements. Utilisez-les conjointement avec

<.> Classes communes pour le contrôle des processus et la communication

1. La classe Queue

est similaire à la Queue fournie avec python .Queue, principalement utilisée pour les petits files d'attente

Syntaxe :


Méthode de classe :
multiprocessing.Queue([maxsize])

qsize()
Renvoie la taille approximative de la file d'attente, car plusieurs processus ou threads ont consommé le file d'attente, donc les données ne sont pas nécessairement correctes

empty()

Déterminez si la file d'attente est vide, si c'est le cas, retournez True, sinon False

full()

Déterminez si la file d'attente est pleine, si c'est le cas, retournez True, sinon False

put(obj[, block[, timeout ]])

Mettez l'objet dans la file d'attente, le bloc de paramètres facultatif est True et le délai d'attente est Aucun

get()

Supprimez l'objet de la file d'attente

#-*- coding:utf8 -*-
from multiprocessing import Process, Queue

def f(q):
    q.put([42,None,'hi'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print q.get()  #打印内容: [42,None,'hi']
    p.join()
2. Classe Pipe

La fonction pipe() renvoie une paire de connexions d'objets, qui peuvent transmettre des messages entre les processus, imprimer des journaux et contrôler les processus. L'objet Pip() renvoie deux connexions d'objet, représentant deux canaux. Chaque objet de connexion a les méthodes send() et recv(). Il convient de noter que deux processus ou plus lisent ou écrivent dans le même tube en même temps. provoquer une confusion dans les données. Après les tests, cela a été directement couvert. De plus, parmi les deux connexions renvoyées, si l'une contient des données send(), l'autre ne peut recevoir des données que via recv()

Le résultat est :
#-*- coding:utf8 -*-
from multiprocessing import Process, Pipe
import time
def f(conn,i):
    print '[{0}]已经执行到子进程:{1}'.format(time.ctime(),i)
    time.sleep(1)
    w = "[{0}]hi,this is :{1}".format(time.ctime(),i)
    conn.send(w)
    conn.close()

if __name__ == '__main__':
    reader = []
    parent_conn, child_conn = Pipe()
    for i in range(4):
        p = Process(target=f, args=(child_conn,i))
        p.start()
        reader.append(parent_conn)
        p.deamon=True

    # 等待所有子进程跑完
    time.sleep(3)
    print '\n[{0}]下面打印child_conn向parent_conn传输的信息:'.format(time.ctime())
    for i in reader:
        print i.recv()


三、Value,Array

在进行并发编程时,应尽量避免使用共享状态,因为多进程同时修改数据会导致数据破坏。但如果确实需要在多进程间共享数据,multiprocessing也提供了方法Value、Array

from multiprocessing import Process, Value, Array

def f(n, a):
    n.value = 3.1415927
    for i in range(len(a)):
        a[i] = -a[i]

if __name__ == '__main__':
    num = Value('d',0.0)
    arr = Array('i', range(10))

    p = Process(target=f, args=(num, arr))
    p.start()
    p.join()

    print num.value
    print arr[:]

*print
3.1415927
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]*

四、Manager进程管理模块

Manager类管理进程使用得较多,它返回对象可以操控子进程,并且支持很多类型的操作,如: list, dict, Namespace、lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value, Array,因此使用Manager基本上就够了

from multiprocessing import Process, Manager

def f(d, l):
    d[1] = '1'
    d['2'] = 2
    d[0.25] = None
    l.reverse()

if __name__ == '__main__':
    with Manager() as manager:
        d = manager.dict()
        l = manager.list(range(10))

        p = Process(target=f, args=(d, l))
        p.start()
        p.join() #等待进程结束后往下执行
        print d,'\n',l

输出:
{0.25: None, 1: '1', '2': 2}
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
可以看到,跟共享数据一样的效果,大部分管理进程的方法都集成到了Manager()模块了

五、对多进程控制的应用实例

    #-*- coding:utf8 -*-
    from multiprocessing import Process, Queue
    import time
    
    def work(pname,q):
        time.sleep(1)
        print_some = "{0}|this is process: {1}".format(time.ctime(),pname)
        print print_some
        q.put(pname)
    
    if __name__ == '__main__':
        p_manag_num = 2  # 进程并发控制数量2
        # 并发的进程名
        q_process = ['process_1','process_2','process_3','process_4','process_5']
        q_a = Queue() # 将进程名放入队列
        q_b = Queue() # 将q_a的进程名放往q_b进程,由子进程完成
    
        for i in q_process:
            q_a.put(i)
    
        p_list = [] # 完成的进程队列
        while not q_a.empty():
            if len(p_list) <p>执行结果:</p><p><img src="https://img.php.cn//upload/image/167/872/710/1542261551928622.png" title="1542261551928622.png" alt="Explication du didacticiel sur le contrôle multi-processus Python (avec exemples)"></p>

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer