When two processes are created and killed, the behaviour is different if print or sleep statements are inserted. It can also be random (different results executing the same program several times) on certain machines and versions of python. Attached two versions, one where the child process mysteriously disappears in the cpython interpreter, and another other one that raises ChildProcessError: [Errno 10] No child processes. This shows up with cpython, all versions I tested (3.7, 3.6, 3.5, 2.7). pypy is unaffected.
I don't think hang.py is correct. If you launch a process using subprocess, the subprocess owns the child process. You should not call waitpid() or os.kill() separately. Also, since you don't keep a reference to the subprocess.Popen object, its destructor will run and may call waitpid() on the child process. Depending on when exactly the destructor runs, it can interfere with your own waitpid() call.