主进程结束后子进程如何作守护进程?主进程存活时如何维持子进程运行?含进程池场景
Hey there! Let's break down your two questions one by one, with practical code examples built from your provided snippet:
First, a quick note: Python's multiprocessing.Process has a daemon flag, but a daemon process will terminate automatically when the main process exits—that's not what we want for a truly independent daemon. To make a child process keep running after the main process exits, we need to detach it from the parent process using os.fork() twice (this is the standard Unix daemonization technique). Here's how to adapt your code:
import os import time from multiprocessing import current_process def doubler(number): result = number * 2 proc_name = current_process().name print('{0} doubled to {1} by: {2}'.format(number, result, proc_name)) # Simulate a long-running task while True: time.sleep(2) print(f'{proc_name} is still running in background...') def create_standalone_daemon(): # First fork: create child process, main process exits immediately pid = os.fork() if pid > 0: os._exit(0) # Main process exits, child becomes orphan # Second fork: avoid being a session leader (prevents terminal-related issues) pid = os.fork() if pid > 0: os._exit(0) # Clean up environment for daemon stability os.chdir('/') # Switch to root directory to avoid mount point locks os.umask(0) # Reset file permission mask # Close all open file descriptors to detach from parent resources for fd in range(os.sysconf("SC_OPEN_MAX")): try: os.close(fd) except OSError: pass # Now this process is a fully detached daemon doubler(10) if __name__ == '__main__': print(f"Main process PID: {os.getpid()}") create_standalone_daemon() print("Main process is exiting now...") os._exit(0)
When you run this, the main process will exit right away, but the daemonized doubler process will keep running in the background.
Absolutely! Both regular Process and Pool can handle this—you just need to make the child process tasks run continuously.
2.1 Using regular Process
Modify your doubler function to include a loop (to keep it running), and start the processes normally. The main process just needs to stay active (e.g., wait for user input or run its own business logic):
import os import time from multiprocessing import Process, current_process def doubler(number): proc_name = current_process().name print('{0} doubled to {1} by: {2}'.format(number, number*2, proc_name)) # Keep the process running indefinitely while True: time.sleep(2) print(f'{proc_name} is still working...') if __name__ == '__main__': numbers = [5, 10, 15, 20, 25] procs = [] for idx, num in enumerate(numbers): proc = Process(target=doubler, args=(num,), name=f"Worker-{idx}") procs.append(proc) proc.start() # Keep main process active (press Enter to stop everything) input("Press Enter to terminate all processes and exit main process...\n") # Clean up child processes gracefully for proc in procs: proc.terminate() proc.join()
2.2 Using multiprocessing.Pool
Process pools work too! Use apply_async to submit persistent tasks asynchronously (so the main process doesn't block), and keep the pool open as long as you need the workers to run:
import os import time from multiprocessing import Pool, current_process def persistent_worker(number): proc_name = current_process().name print(f"Worker {proc_name} started with number {number}") # Continuous task loop while True: time.sleep(2) print(f'{proc_name} is processing {number}...') if __name__ == '__main__': # Create a pool with 3 worker processes with Pool(processes=3) as pool: numbers = [5, 10, 15] # Submit persistent tasks asynchronously results = [pool.apply_async(persistent_worker, args=(num,)) for num in numbers] # Keep main process running (interrupt with Ctrl+C) try: while True: time.sleep(1) except KeyboardInterrupt: print("\nMain process interrupted—shutting down pool...") pool.terminate() pool.join()
The pool's workers will keep running their persistent tasks until you explicitly terminate the pool or the main process exits.
内容的提问来源于stack exchange,提问作者bluebamus

