python limiter nombre de processus

Le problème exposé dans ce sujet a été résolu.

Bonjour, je voudrais limiter le nombre de processus de mon programme à 4. C’est a dire que si mon programme à plus de 4 processus actif il attend que les autres se termine avant d’en lancer d’autre

voici mon code simplifié, je voudrais que au lieu de crée 100 processus d’un coup, python se limite à 4 seulement (définie dans ma variable number_of_core)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from multiprocessing import Process, Queue, Manager

def funct1(data):
    data.append(1)



if __name__ == '__main__':
    manager = Manager()
    data = manager.list()

    procs=[]
    number_of_core=4

    for i in range(0,100):
        p = Process(target=funct1, args=(data,))
        p.start()   
        procs.append(p)


    for process in procs :
        process.join()


    print(data)
    print(len(data))

dans mon cas l’ordre des éléments à ajouter dans ma liste "data" n’a pas d’importance je souhaite ajouter 100 éléments dans la liste, mais pas plus de 4 en même temps.

ici, c’est un exemple bateau mais dans mon vrai code, la fonction funct1 effectue des traitements plus lourds que je voudrais paralléliser, mais si python me crée 100 process d’un coup sa sature (pour rien), donc je voudrais le limiter au nombre de coeur de ma machine : 4 (je sais qu’il existe une fonction dans multiprocessing pour connaitre le nombre de cpu sur sa machine)

+0 -0

Salut,

Ce que tu cherches à faire est réalisable, mais il te faudra un fil dédié pour inspecter la liste des processus, et lancer le suivant quand un se termine.

Ça n’est pas exactement la manière dont tu décris la solution, mais je pense que la classe Pool du module multiprocessing serait plus pertinente pour résoudre ton problème.

Avec Pool, la logique est légèrement différente : tu lance 4 process, mais ils peuvent très bien traiter 100 jeux de données différents. Ainsi, chaque process va traiter un jeu de données après l’autres jusqu’a ce que toutes les données soient traitées.

1
print(p.map(f, range(100)))
+0 -0

je suis désolé mais je ne comprend pas… voila ce que j’ai fais :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from multiprocessing import Manager, Pool

def funct1(data):
    data.append(1)



if __name__ == '__main__':
    manager = Manager()
    data = manager.list()

    procs=[]
    number_of_core=4

    for i in range(0,25):
        p = Pool(4)
        p.map(funct1, data)

    print(data)
    print(len(data))

Il y a plusieurs choses qui ne vont pas dans ton exemple, voici un exemple plus simple qui devrait fonctionner :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from multiprocessing import Pool

def funct1(n):
    return n**2

if __name__ == '__main__':
    number_of_core=4

    p = Pool(number_of_core)
    result = p.map(funct1, range(0,25))

    print(result)
    print(len(result))
+0 -0

ok je vois, merci.

mais mon exemple n’étais peut être pas représentatif, en faite à la place de range(0,25) il s’agit d’une liste de nombres qui peut varier (il peut y en avoir 100,1000,1,2,23…) maliste= [1,1.5,7,5,5.644,3,4] en l’occurrence, je souhaite au maximum traiter 4 élément en même temps, j’ai l’impression qu’il vas falloir faire du découpage de liste ?

Non.

En gros Pool c’est le truc qui va géré pour toi les processus. Si tu le crée avec 4 en argument, il va toujours n’utiliser que 4 processus. Ensuite la méthode map : tu lui donne 2 choses : une fonction et un itérateur. Que va t’elle faire ? Elle va prendre les 4 premiers elements de ton itérateur et executer ta fonction avec chacune de ces valeurs dans un processus. Dès qu’un processus va avoir finir de calculer une valeur, elle va redonner une nouvelle valeur avec ce processus… Elle te renvoie à la fin la liste des tous les éléments calculés.

Dans le code que je t’ai donné, le range(25) sert d’exemple mais ne change pas le nombre de processus. Tu peux lui donner n’importe quelle liste. C’est le Pool(number_of_core) qui limite le nombre de processus. Essai tu verra bien.

je me rend compte que pool a quand même des limites, résults ajoute des éléments dans une liste, peut on plutôt faire une extend ou bien utiliser un manager.list ? dans mon cas, la funct2 ressemble plutot à ceci :

1
2
3
4
5
6
def funct1(n):
    maliste=[]
    maliste.append(n**2)
    return maliste

`
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte