【问题标题】:Starting and stopping snmpd subprocess with global variable使用全局变量启动和停止 snmpd 子进程
【发布时间】:2016-03-19 20:58:20
【问题描述】:

我正在使用子进程启动 snmpd,将对此的引用存储为全局变量,然后想稍后终止该进程。

我这样开始这个过程:

snmp_proc = subprocess.Popen(['snmpd', '-p', pid_file,'-Lf', log_file],
                              stdout=open(os.devnull,'w'),stderr=subprocess.STDOUT)

这正确启动但似乎也创建了某种僵尸进程? ps ax 输出给出:

1716 ?        Z      0:00 [snmpd] <defunct>
1718 ?        S      0:00 snmpd -p /var/run/snmpd.pid -Lf /var/log/snmpd

现在,当我稍后尝试终止该进程时,只会终止已失效的僵尸进程,而其他进程仍然存在。知道我做错了什么吗? 以下是停止 snmpd 的代码:

def stop_snmp(): 
    global snmp_proc
    if not snmp_proc:
        return 
    snmp_proc.terminate()
    snmp_proc.wait()
    snmp_proc = None

【问题讨论】:

    标签: python global-variables subprocess snmp snmpd


    【解决方案1】:

    &lt;defunct&gt; 表示子进程已死,但您尚未读取其退出状态(使用snmp_proc.wait())。

    我的猜测:snmpd 启动一个守护进程 (double fork, etc) 并立即返回,即,为了避免僵尸,在这里使用 subprocess.check_call() 而不是 subprocess.Popen()

    要停止启动的守护程序服务,应该有一个特殊的命令。如果没有,则从 pid_file 读取 pid 并使用它向守护程序发送信号 (os.kill()) 以杀死它。

    我刚刚通过传递 -f 来禁用分叉解决了这个问题

    是的,禁用守护程序行为是另一种选择。在这种情况下,snmpd 在同一进程中运行服务(由 Popen() 启动),因此它不应成为僵尸,除非出现致命错误,例如启动失败。

    【讨论】:

    • 我刚刚通过传递 -f 禁用分叉解决了这个问题,感谢您的回复,因为它可以帮助我更好地理解事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多