Q: Using multiprocessing.join() is not blocking execution Here is a bit of code I've run. I'm trying to make sure that all my processes finish before I move on through my code, but it's not happening as I expect.
import sys
import multiprocessing as mp
import time
import random

def testJoin(argin):
    name =  mp.current_process().name
    exStartTime = time.time()
    time.sleep(argin * random.random())
    print(name + ' took %d seconds' %(time.time() - exStartTime))
    sys.stdout.flush()


if __name__ == '__main__':
    instances = [10, 10, 10, 10]
    jobs = []
    for k in instances:
        p = mp.Process(target = testJoin, args = (k,))
        jobs.append(p)
        p.start()
    p.join()

print('End of Program')

Here is what's being output:
End of Program
Process-4 took 1 seconds
End of Program
End of Program
Process-2 took 4 seconds
End of Program
Process-1 took 9 seconds
End of Program
Process-3 took 9 seconds

Where I'm confused is that I don't expect to see "End of Program" printed more than once, and I certainly don't expect to see it printed until all of my four processes have ended. What am I missing?

A: The behavior you describe does not happen under Unix, but it does under Windows. 
Windows lacks os.fork, so in order to start a subprocess, multiprocessing starts a new Python interpreter and imports the calling module. 
The if __name__ == "__main__" protects code from getting executed when imported. Since the 
print('End of Program')

is not inside the if-statement, it gets executed once for each time the calling module is imported and once by the main process. 
The solution is to simply put the print call inside the if-statement.
