I have been experimenting with multiprocessing, and running into a mindblock with daemons.
I have one daemon and one non-daemon process, the daemon emitting output every one second indefinitely, while the non-daemon prints output immediately upon start, sleeps for 3 seconds, then prints again and returns.
The problem is, the expected output from the daemon process doesn't show up at all.
Reviewing past SO questions on daemons, the common issues appear to be either the other processes ending before the daemon, or the stdout requiring flushing to show output. Both have (I think) been addressed, however I continue to only see printed output from non-daemonic processes.
The code:
from multiprocessing import Process, current_process
import sys
import time
def worker():
"""
Announce that the process has started, sleep 3 seconds
then announce that the process is ending.
"""
name = current_process().name
print name, 'starting...'
sys.stdout.flush()
time.sleep(3)
print name, 'ending...'
sys.stdout.flush()
return
def daemon():
"""
Announce that the process has started, beep, then beep
once every second
"""
name = current_process().name
print name, 'starting...'
print 'beep...'
sys.stdout.flush()
while True:
time.sleep(1)
print 'beep...'
sys.stdout.flush()
if __name__=='__main__':
d = Process(target=daemon)
d.daemon = True
d.start()
p = Process(target=worker)
p.daemon = False
p.start()
Expected Output:
Process-1 starting... # Order here may vary
beep...
Process-2 starting...
beep...
beep...
Process-2 ending... #There may or may not be another beep here
What actually gets produced:
Process-2 starting...
Process-2 ending...
Any advice on why this is happening would be truly appreciated.
You can get a clearer picture of the order of events by turning on logging by placing
import multiprocessing as mp
logger = mp.log_to_stderr(logging.INFO)
after the other import statements. Then your program will yield something like:
[INFO/Process-1] child process calling self.run()
[INFO/MainProcess] process shutting down
Process-1 starting...
beep...
[INFO/Process-2] child process calling self.run()
[INFO/MainProcess] calling terminate() for daemon Process-1
Process-2 starting...
[INFO/MainProcess] calling join() for process Process-2
Process-2 ending...
[INFO/Process-2] process shutting down
[INFO/Process-2] process exiting with exitcode 0
[INFO/MainProcess] calling join() for process Process-1
Thus, the main starts shutting down first, then it terminates Process-1, the daemon process. That's why you do not see any more beeps while Process-2 continues.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With