You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用start-stop-daemon将Django服务化时多PID无法完全停止求助

Fixing Incomplete Django Service Stop on Ubuntu 16.04

Hey there, let's tackle this issue where your Django service leaves leftover processes even after running the stop command. The multiple PIDs you're seeing are almost certainly child processes spawned by either the virtualenv wrapper, Django's runserver (especially if auto-reload is enabled), or a subshell created by your init script. Here's how to fix it:

1. Kill the Entire Process Group Instead of a Single PID

Most of the time, those extra PIDs are part of the same process group as the main PID in your $PIDFILE. Instead of just killing the single PID, you can kill the entire group to stop all related processes at once.

Update the stop section of your /etc/init.d/initfile script to use this approach:

stop() {
    if [ -f $PIDFILE ]; then
        PID=$(cat $PIDFILE)
        # Kill the entire process group (note the negative sign before PID)
        if kill -- -$PID 2>/dev/null; then
            echo "Successfully stopped Django service and all child processes"
            rm -f $PIDFILE
        else
            echo "Service might not be running, or failed to stop all processes"
        fi
    else
        echo "PID file $PIDFILE doesn't exist - service isn't running"
    fi
}

The kill -- -$PID syntax sends a signal to every process in the group led by $PID, ensuring no child processes are left behind.

2. Avoid Spawning Subshells in Your Startup Command

If your init script uses shell features like pipes, &, or nested commands, it might create extra subshell processes that aren't tied to the main PID. Use exec to replace the current shell with your Django process, which eliminates subshells:

Modify your startup command to look something like this:

start() {
    # Activate virtualenv and exec the Django runserver directly
    cd /path/to/your/django/project
    exec $VIRTUAL_ENV/bin/python manage.py runserver 0.0.0.0:8000 > /var/log/django.log 2>&1 &
    echo $! > $PIDFILE
    echo "Django service started with PID $(cat $PIDFILE)"
}

Using exec ensures the main process is the Django runserver itself, so the PID in $PIDFILE is the root of the process tree.

3. Verify Process Relationships First

To confirm exactly which processes are tied to your service, run this command with the main PID from your $PIDFILE:

pstree -p 22875

This will show you the full tree of parent and child processes. You'll see exactly how the extra PIDs (22878, 22880) are linked to the main process, which can help you fine-tune your stop logic.

4. Fallback: Use pkill to Match Process Command Lines

If the process group method doesn't work for some reason, you can use pkill to target all processes running your Django runserver command:

pkill -f "python /path/to/your/django/project/manage.py runserver"

Just make sure the command string is specific enough to avoid killing unrelated Python processes. Add this to your stop function as a backup if needed.

Test your updated script by starting the service, checking the PIDs with ps -fu root, then running the stop command and verifying all related processes are gone with ps -fu root | grep django.

内容的提问来源于stack exchange,提问作者rishardcarranza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:58:25