Aufruf von Funktion mit Prozessen gibt Ergebnis mehr als ein Mal aus

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
CptK
User
Beiträge: 7
Registriert: Sonntag 16. Januar 2022, 12:04
Wohnort: Darmstadt

Hallo, ich habe folgende kleine Anwendung:

Code: Alles auswählen

from multiprocessing import Process, Queue

def reduce(que, data):
    que.put(sum(data))

def calc_mean_serial(data):
    return sum(data) / len(data)

def calc_mean_parallel(data, num_procs=8):
    sum = 0
    if __name__ == '__main__':
        chunk = (int) (len(data) / num_procs)
        procs = []
        q = Queue()

        for i in range(num_procs):
            p = Process(target=reduce, args=(q, data[i*chunk:i*chunk+chunk if i != num_procs-1 else None]))
            p.start()
            procs.append(p)

        for p in procs:
            p.join()

        while not q.empty():
            sum = sum + q.get()

    return sum / len(data)

print("serial", calc_mean_serial([i for i in range(1,100000)]))
print("parallel", calc_mean_parallel([i for i in range(1,100000)]))
Nun hätte ich gerne folgende Ausgabe:

Code: Alles auswählen

serial 50000.0
parallel 50000.0
stattdessen beomme ich aber

Code: Alles auswählen

serial 50000.0
serial 50000.0
parallel 0.0
serial 50000.0
parallel 0.0
serial 50000.0
parallel 0.0
serial 50000.0
parallel 0.0
serial 50000.0
parallel 0.0
serial 50000.0
parallel 0.0
serial 50000.0
parallel 0.0
serial 50000.0
parallel 0.0
parallel 50000.0
Sprich: jede Ausgabe wird so oft vorgenommen, wie ich Prozesse habe. Das ist natürlich nicht das gewünschte Ergebnis. Wie kann ich das korrigieren, dass es wie gewünscht funktioniert?

LG
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Das `if __name__ == '__main__':` ist an der falschen Stelle.

Code: Alles auswählen

from multiprocessing import Process, Queue

def reduce(queue, data):
    queue.put(sum(data))

def calc_mean_serial(data):
    return sum(data) / len(data)

def calc_mean_parallel(data, num_procs=8):
    chunk = len(data) // num_procs
    queue = Queue()

    processes = []
    for i in range(num_procs):
        process = Process(target=reduce, args=(queue, data[i*chunk:i*chunk+chunk if i != num_procs-1 else None]))
        process.start()
        processes.append(process)

    for process in processes:
        process.join()

    total = 0
    while not queue.empty():
        total += queue.get()
    return total / len(data)

if __name__ == '__main__':
    print("serial", calc_mean_serial([i for i in range(1,100000)]))
    print("parallel", calc_mean_parallel([i for i in range(1,100000)]))
Antworten