You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python命令行调用函数后如何不等待子进程直接返回?

Solution to Detach Child Process and Exit Parent Immediately

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=True creates a new process session, so the child isn't tied to the parent's terminal.
  • Redirecting stdout/stderr prevents 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 after func() completes, leaving the detached func2 process 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:

  1. The first fork creates a child process, which the parent immediately abandons (returns from async_process).
  2. The child creates a new session to break ties with the parent's terminal.
  3. 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

火山引擎 最新活动