88 votes

Comment incrémenter un compteur partagé à partir de plusieurs processus ?

J'ai des problèmes avec le module multiprocessing. J'utilise un Pool des travailleurs avec sa méthode map pour analyser simultanément beaucoup de fichiers. Chaque fois qu'un fichier a été traité, je voudrais avoir un compteur mis à jour afin que je puisse garder une trace du nombre de fichiers restant à traiter. Voici un exemple de code :

import os
import multiprocessing

counter = 0


def analyze(file):
    # Analyze the file.
    global counter
    counter += 1
    print counter


if __name__ == '__main__':
    files = os.listdir('/some/directory')
    pool = multiprocessing.Pool(4)
    pool.map(analyze, files)

Je n'arrive pas à trouver une solution.

45voto

serbaut Points 2351

Contre-classe sans bogue de condition de course :

class Counter(object):
    def __init__(self):
        self.val = multiprocessing.Value('i', 0)

    def increment(self, n=1):
        with self.val.get_lock():
            self.val.value += n

    @property
    def value(self):
        return self.val.value

15voto

lbsweek Points 528

Un exemple extrêmement simple, modifié de la réponse de jkp :

from multiprocessing import Pool, Value
from time import sleep

counter = Value('i', 0)
def f(x):
    global counter
    with counter.get_lock():
        counter.value += 1
    print("counter.value:", counter.value)
    sleep(1)
    return x

with Pool(4) as p:
    r = p.map(f, range(1000*1000))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X