Shailesh Appukuttan
Shailesh Appukuttan

Reputation: 830

Python fork process inside Jupyter Notebook

I am running the following code inside a Jupyter notebook:

import os

print("Start")
pid = os.fork()

if pid == 0:
    print("Child")
    os._exit(os.EX_OK)
else:
    print("Parent")
    
if pid != 0:
    # parent
    pid, status = os.waitpid(pid, 0)
    print("Done")

I am getting the following output "almost" every time:

Child
Start
Parent
Done

How is it that "Child" gets printed before "Start"? Almost 9 out of 10 times, I get the output as above. Occasionally, I find what is intuitively expected ("Start" being printed first, followed by "Parent" or "Child" and then finally ending with "Done").

When I run the same code directly on the console, I get the expected outcome each time:

Start
Parent
Child
Done

Why do we see this peculiar behavior within Jupyter notebooks? And how to avoid this?

Upvotes: 3

Views: 1024

Answers (2)

tdelaney
tdelaney

Reputation: 77407

It looks like stdout is block buffered, not line buffered. The parent "Start\n" is waiting in the output buffer. The child "Child\n" starts out in its own output buffer but is flushed on exit. You could verify with import sys;print(sys.stdout.isatty()). The solution is to flush often

print("Start", flush=True)

or if you have multiple things to print,

print("Foo")
print("Bar")
sys.stdout.flush()

Upvotes: 3

Brody Critchlow
Brody Critchlow

Reputation: 63

At the moment there is no way to avoid this that I know. Maybe there is a setting that is enabled. You could also try to add a wait. Before you print child or parent, etc. Hopefully this helps a bit.

Sleep like this:

import time
 
# Wait for 5 seconds
time.sleep(5)
 
# Wait for 300 milliseconds
# .3 can also be used
time.sleep(.300)

I would suggest waiting like .5 milliseconds to 1 second

Upvotes: 1

Related Questions