python master/child looping unintentionally
Question: Problem: I expect child to time out and be done. but instead it times out and
begins to run again.

Can anyone tell me why this program runs forever? I expect it to run one time
and exit...

Here is a working program. Master threads a function to spawn a child. Works
great except it ends up looping.

Here is the master:

    
    
    # master.py
    import multiprocessing, subprocess, sys, time
    
    def f():
        p = subprocess.Popen(["C:\\Python32\\python.exe", "child.py"])
        # wait until child ends and check exit code
        while p.poll() == None:
            time.sleep(2)
        if p.poll() != 0:
            print("something went wrong with child.py")
    
    # multithread a function process to launch and monitor a child
    p1 = multiprocessing.Process(target = f())
    p1.start()
    

and the child:

    
    
    # child.py
    import socket, sys
    
    def main(args):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            sock.settimeout(10)
            sock.bind(('', 54324))
            data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
            print(data)
            sock.close()
            return 0
        except KeyboardInterrupt as e:
            try:
                sock.close()
                return 0
            except:
                return 0
    
    if __name__ == "__main__":
        sys.exit(main(sys.argv))
    


Answer: The problem is that your `master.py` doesn't have an `if __name__ ==
'__main__'` guard. On Windows, `multiprocessing` has to be able to reimport
the `main` module in the child process, and if you don't use this `if` guard,
you will re-execute the `multiprocessing.Process` in the child (resulting in
an accidental forkbomb).

To fix, simply put all of the commands in `master.py` in the `if` guard:

    
    
    if __name__ == '__main__':
        # multithread a function process to launch and monitor a child
        p1 = multiprocessing.Process(target = f())
        p1.start()
    

