0

Je tente de faire du multi-threading propre mais peut-être que mon approche est fausse.Python - Exécution de nombreux types de threads sans épuiser les ressources

J'ai une classe de filetage BaseFix avec 6 types d'enfants différents, dont l'un est CommandFix Filetage, un autre est ParamFix Fil.

Leurs fonctions run ont un code différent à l'intérieur, mais utilisent principalement la fonction subprocess.run.

class CommandFix(BaseFix): 

    def __init__(self, group=None, target=None, name=None, 
      args=(), kwargs=None, verbose=None): 

     super(CommandFix, self).__init__(group=group, target=target, 
         name=name, kwargs=kwargs, verbose=None) 


    def _execute_command(self): 
     self.stdout_log.write("fixing {} : running command {}".format(
      self.rule_id, 
      self.command)) 

     try: 
      cp = subprocess.run(self.command, 
       shell=True, check=True, 
       stdout=self.stdout_log, 
       stderr=self.stderr_log 
       ) 
     except subprocess.CalledProcessError as e: 
      self.stderr_log.write("error fixing {} : {}".format(
       self.rule_id, 
       e)) 

      # TO-DO: Handle error with retry or similar 
      # right now just return false 
      return False 

     return True 

    def _verify_command(self): 
     pass 

    def run(self): 

     # execute the command 
     if self._execute_command(): 
      # now run the verification 
      pass 
     else: 
      # TO-DO: error handling 
      pass 

J'ai sur 200 fixe d'environ 6 types différents. Je vérifie leur type de correctif, instanciation puis le correctif nécessaire et appeler run comme ceci:

def _fix(key, rule): 
    expr = "./{}fixtext".format(NS) 
    fixtext = rule.find(expr) 

    expr = "./{}div".format(NS1) 
    fixtext = fixtext.find(expr).getchildren()[0].getchildren()[0].text 

    if fixtext.find('Run the following command') > 0: 
     fix = CommandFix(rule, stdout_log, stderr_log, key) 

    elif fixtext.find('Set the following') > 0: 
     # fix = SomeOtherFix() 
     pass 

    elif fixtext.find('For 32 bit systems') > 0: 
     # fix = SomeOtherKindOfFix() 
     pass 

    fix.run() 

# there are only 200 but assume there are 2 million 
for key, rule in rules.items(): 
    _fix(key, rule) 

Ce que je voudrais faire est de nettoyer ce afin que je n'exécutais X number of fixes à un moment donné pour que je n » t épuiser les ressources du système.

Répondre

1

Comme vous l'avez déjà dit dans les balises de votre question: utilisez une piscine. Tant que vos *Fix() s appellent subprocess.run(), ils engendrent de toute façon de nouveaux processus de parallélisme réel. Par conséquent, un pool de threads est suffisant:

from multiprocessing.dummy import Pool # wrapper around the threading module 
#from multiprocessing import Pool   # real processes instead of threads 
[...] 
pool = Pool(5)       # number of fixes at once 
pool.starmap(_fix, rules.items())