Python命令行调用函数后如何不等待子进程直接返回?
The issue you're facing happens because when you run Python via python -c, the main process waits for all non-daemon child processes (created with multiprocessing.Process) to complete before exiting. Setting daemon=True would terminate the child when the parent exits, which isn't what you want. To fix this, we need to completely detach the child process from the parent so it can run independently even after the parent exits.
Here are two reliable approaches:
Approach 1: Use subprocess.Popen with Session Detachment
This is the simplest and most readable method. We'll start the child process as a separate, detached Python process using subprocess.Popen with start_new_session=True, which creates a new session and detaches it from the parent's terminal.
Modified script.py:
import subprocess import sys def func(): async_process() print('OK') return 123 def func2(): # Example long-running task (replace with your actual code) import time while True: print("Child process is running...") time.sleep(5) def async_process(): # Start func2 in a detached process subprocess.Popen( [sys.executable, "-c", "from script import func2; func2()"], start_new_session=True, stdout=subprocess.DEVNULL, # Redirect output to avoid terminal clutter stderr=subprocess.DEVNULL # Alternatively, redirect to a log file: # stdout=open('child.log', 'a'), # stderr=open('child_errors.log', 'a') )
How it works:
start_new_session=Truecreates a new process session, so the child isn't tied to the parent's terminal.- Redirecting
stdout/stderrprevents the child process from inheriting the parent's terminal, which avoids unexpected output or blocking. - When you run
python -c "from script import func; func()", the main process exits immediately afterfunc()completes, leaving the detachedfunc2process running in the background.
Approach 2: Double-Fork with os Module (Unix/Linux Only)
This is a lower-level Unix-specific technique that creates an orphaned grandchild process, which gets adopted by the system init process (e.g., systemd). This ensures the parent can exit without waiting for the child.
Modified script.py:
import os import sys def func(): async_process() print('OK') return 123 def func2(): # Example long-running task (replace with your actual code) import time while True: print("Child process is running...") time.sleep(5) def async_process(): # First fork: create a child process pid = os.fork() if pid > 0: # Parent process (func's caller) returns immediately return else: # First child: create a new session to detach from parent terminal os.setsid() # Second fork: create a grandchild process pid2 = os.fork() if pid2 > 0: # Exit first child, leaving grandchild orphaned sys.exit(0) else: # Grandchild runs the actual task func2() sys.exit(0)
How it works:
- The first fork creates a child process, which the parent immediately abandons (returns from
async_process). - The child creates a new session to break ties with the parent's terminal.
- The child forks again to create a grandchild, then exits. The grandchild becomes orphaned and is adopted by the system init process, so it continues running even after the original parent exits.
Testing the Solution
Run the command line as before:
python -c "from script import func; func()"
You'll see OK printed immediately, and the terminal returns to prompt. The func2 process will keep running in the background (you can verify with ps aux | grep script.py).
Content of the question来源于stack exchange,提问作者cramer




