'Big troubles with easy multiprocessing code: runtime error (python)

I wrote an easy code in Python just to learn how to use multiprocessing. So I defined a scrap function:

def useless_function(exp):
    for j in range(int(10**exp):
        pass

If I execute a code like the following, the first for loop works, the second leads the pc to pure madness:

import time
import multiprocessing as mp

def useless_function(exp):
    for j in range(int(10**exp)):
        pass

exp=8
start=time.perf_counter()
for i in range(5):
    useless_function(exp)
    print("No multiprocessing, I got to iteration ",i)

middle=time.perf_counter()
print("No multiproc., process ended in ",middle-start," seconds.")

if __name__=="__main__":
    processes=[]
    for j in range(5):
        p=mp.Process(target=useless_function,args=(exp,))
        p.start()
        processes.append(p)

    for process in processes:
        process.join()
        print("WITH multiproc. I got to step ",processes.index(process))
    finish=time.perf_counter()
    print("With multiproc. process ended in ",finish-middle," seconds.")

And the output I get is pretty odd: it looks like the multiprocess part goes back to the non-parallelized for loop and executes it. How can it even go back in the code?

No multiproc., I got to iteration  0
No multiproc., I got to iteration  1
No multiproc., I got to iteration  2
No multiproc., I got to iteration  3
No multiproc., I got to iteration  4
No multiproc., process ended in  9.914604499999996  seconds.
No multiproc., I got to iteration  0
No multiproc., I got to iteration  0
No multiproc., I got to iteration  0
No multiproc., I got to iteration  0
No multiproc., I got to iteration  0
No multiproc., I got to iteration  1
No multiproc., I got to iteration  1
No multiproc., I got to iteration  1
No multiproc., I got to iteration  1
No multiproc., I got to iteration  1
No multiproc., I got to iteration  2
No multiproc., I got to iteration  2
No multiproc., I got to iteration  2
No multiproc., I got to iteration  2
No multiproc., I got to iteration  2
No multiproc., I got to iteration  3
No multiproc., I got to iteration  3
No multiproc., I got to iteration  3
No multiproc., I got to iteration  3
No multiproc., I got to iteration  3
No multiproc., I got to iteration  4
No multiproc., process ended in  25.363089899999977  seconds.
No multiproc., I got to iteration  4
No multiproc., process ended in  25.52356009999994  seconds.
No multiproc., I got to iteration  4
No multiproc., process ended in  25.786010900000065  seconds.
No multiproc., I got to iteration  4
No multiproc., process ended in  25.977586800000154  seconds.
No multiproc., I got to iteration  4
No multiproc., process ended in  27.87371519999988  seconds.
WITH multiproc. I got to step  0
WITH multiproc. I got to step  1
WITH multiproc. I got to step  2
WITH multiproc. I got to step  3
WITH multiproc. I got to step  4
With multiproc. process ended in  32.527025200000026  seconds.

No error message, just nonsense. What should I do?



Solution 1:[1]

Unfortunately it's hard to notice it in the documentation, but there is as secion about how process is run.

Generally on linux processes are spawn by fork command which shares resources with parent. It would work as you expect here. However Windows has no such kernel support and it uses spawn, so run your .py script again for each process - that's why without if name == __main__ it causes error and that's why you see your file level functions are run many times.

In your case it will be enough to put file level loop to a function.

Here and here I found useful blogs that can give you more insight.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 kosciej16