2015-12-03 1 views
3

J'ai des problèmes avec le gel Python lorsque j'essaie d'utiliser le module multiprocessing. J'utilise Spyder 2.3.2 avec Python 3.4.3 (j'ai déjà rencontré des problèmes spécifiques à iPython).Multiprocessing Python suspendu sur pool.join()

je l'ai réduit à la MWF suivante: importation multitraitement

def test_function(arg1=1,arg2=2): 
    print("arg1 = {0}, arg2 = {1}".format(arg1,arg2)) 
    return None 

pool = multiprocessing.Pool(processes=3) 
for i in range(6): 
    pool.apply_async(test_function) 

pool.close() 
pool.join() 

Ceci, sous sa forme actuelle, devrait produire juste six itérations identiques de test_function. Cependant, alors que je peux entrer les commandes sans tracas, quand je donne la commande pool.join(), iPython se bloque, et je dois redémarrer le noyau.

La fonction fonctionne parfaitement lorsque vous avez terminé en série (l'étape suivante dans mon MWE serait d'utiliser pool.apply_async(test_function,kwds=entry).

for i in range(6): 
    test_function() 
arg_list = [{'arg1':3,'arg2':4},{'arg1':5,'arg2':6},{'arg1':7,'arg2':8}] 
for entry in arg_list: 
    test_function(**entry) 

J'ai (de temps en temps, et je suis incapable de reproduire de manière fiable) viennent à travers un message d'erreur de ZMQError: Address already in use, ce qui m'a conduit à this bug report, mais qui a précédé mon code avec soit multiprocessing.set_start_method('spawn') ou multiprocessing.set_start_method('forkserver') ne semble pas fonctionner.

quelqu'un peut-il offrir une aide/conseil? Merci d'avance si oui.

+0

Je ne l'ai jamais vu une méthode de démarrage étant explicitement appelé, et l'insertion de 'pool.start()' 'juste après la piscine = multiprocessing.Pool (processus = 3)' me donne 'AttributeError: objet 'Pool' n'a pas d'attribut 'start', mais n'hésitez pas à me dire que je ne comprends pas quelque chose! –

+0

La commande 'start' convient à la fonction' Process', pas à la fonction 'Pool', autant que je puisse le voir, à moins que je ne comprenne mal l'implémentation. –

Répondre

2

@Anarkopsykotik est correct: vous devez utiliser un main, et vous pouvez l'imprimer en retournant un résultat au thread principal.

Voici un exemple de travail.

import multiprocessing 
import os 

def test_function(arg1=1,arg2=2): 
    string="arg1 = {0}, arg2 = {1}".format(arg1,arg2) +" from process id: "+ str(os.getpid()) 
    return string 

if __name__ == '__main__': 
    pool = multiprocessing.Pool(processes=3) 
    for i in range(6): 
     result = pool.apply_async(test_function) 
     print(result.get(timeout=1)) 
    pool.close() 
    pool.join() 
1

Deux choses me viennent à l'esprit qui pourraient causer des problèmes. Tout d'abord, dans le doc, il y a un avertissement sur l'utilisation de l'interpréteur interactif avec le module de multitraitement: https://docs.python.org/2/library/multiprocessing.html#using-a-pool-of-workers

Functionality within this package requires that the main module be importable by the children. This is covered in Programming guidelines however it is worth pointing out here. This means that some examples, such as the Pool examples will not work in the interactive interpreter.

Deuxièmement: vous pouvez récupérer une chaîne avec votre fonction async, puis l'afficher à partir de votre principale fil. Je ne suis pas sûr que les threads enfants ont accès à la sortie standard, qui peut être verrouillée au thread principal.

+0

Merci pour le pointeur initial - vous avez entièrement raison. –