2017-05-01 2 views
0

Ich versuche, die Listen innerhalb des Wörterbuchs clean_txt in einer anderen Funktion zu manipulieren, aber es funktioniert nicht und ich am Ende mit leeren Listen innerhalb des Diktats.Kann eine Variable nicht lokal zu einer Funktion in einer anderen Funktion mutieren

Ich verstehe, dass sowohl Listen als auch Dicts veränderbare Objekte sind, was ist das Problem hier?

def process_questions(i, question_list, questions, question_list_name): 
    ''' Transform questions and display progress ''' 
    print('processing {}: process {}'.format(question_list_name, i)) 
    for question in questions: 
     question_list.append(text_to_wordlist(str(question))) 

@timeit 
def multi(n_cores, tq, qln): 
    procs = [] 
    clean_txt = {} 
    for i in range(n_cores): 
     clean_txt[i] = [] 

    for index in range(n_cores): 
     tq_indexed = tq[index*len(tq)//n_cores:(index+1)*len(tq)//n_cores] 
     proc = Process(target=process_questions, args=(index, clean_txt[index], tq_indexed, qln,)) 
     procs.append(proc) 
     proc.start() 

    for proc in procs: 
     proc.join() 

    print('{} records processed from {}'.format(sum([len(x) for x in clean_txt.values()]), qln)) 
    print('-'*100) 

Antwort

1

Sie verwenden Prozesse nicht Threads.

Wenn der Prozess erstellt wird der Speicher Ihres Programms kopiert und jeder Prozess arbeitet an einem eigenen Satz, daher ist es nicht freigegeben.

Hier ist eine Frage, die Sie verstehen helfen: Multiprocessing vs Threading Python

Wenn Sie Speicher wollen zwischen Prozessen teilen Sie Threads in semaphores oder verwenden Sie stattdessen aussehen sollte. Es gibt auch andere Lösungen, um Daten zu teilen, wie Warteschlangen oder Datenbank usw.

1

Sie sind an clean_txt[index] von einem anderen Prozess anfügen. clean_txt[index] gehört zum Hauptpython-Prozess, der es erstellt hat. Da ein Prozess nicht auf den Speicher eines anderen Prozesses zugreifen oder diesen ändern kann, können Sie ihn nicht anhängen. (Nicht wirklich. Siehe Bearbeiten unten)

Sie müssen Shared Memory erstellen.

können Sie Manager verwenden, um gemeinsam genutzten Speicher zu erstellen, so etwas wie dieses

from multiprocessing import Manager 
manager = Manager() 
... 
    clean_txt[i] = manager.list() 

Jetzt können Sie diese Liste in dem anderen Prozess anhängen.

bearbeiten -

Meine Erklärung über clean_txt war nicht klar. Danke an @Maresh.

Wenn ein neuer Process erstellt wird, wird der gesamte Speicher kopiert. Das Ändern der Liste im neuen Prozess wirkt sich also nicht auf die Kopie im Hauptprozess aus. Sie brauchen also einen gemeinsamen Speicher.

+0

Es ist ein bisschen irreführend zu sagen, dass es zum Parent-Prozess gehört :) – Maresh

+0

@Maresh Er macht 'clean_txt [i] = []' im Hauptprozess, so dass diese Liste zum Hauptprozess gehört, oder? –

+0

Nun, jeder Prozess wird seinen eigenen Speicherplatz haben, kopiert aus dem übergeordneten Prozess "Eins, es ist wichtig zu verstehen, dass beim Spielen mit Multiprocessing. Am Ende hast du recht, diese genaue Speicheradresse gehört zu den Eltern, aber es sollte in der Erklärung IMO klarer sein. – Maresh

Verwandte Themen