- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我遇到一些使用看门狗进程运行的 python 进程的奇怪问题。
watchdog 进程是用 python 编写的并且是父进程,并且有一个名为 start_child(name) 的函数,它使用 subprocess.Popen 打开子进程。记录 Popen 对象,以便看门狗可以使用 poll() 监视进程,并最终在需要时使用 terminate() 结束它。如果 child 意外死亡,看门狗会再次调用 start_child(name) 并记录新的 Popen 对象。
有7个子进程,都是python的。如果我手动运行任何子级,我可以使用 kill 发送 SIGTERM 或 SIGINT 并获得我期望的结果(进程结束)。
但是,当从看门狗进程运行时,子进程只会在 FIRST 信号后结束。当看门狗重新启动子进程时,新的子进程不再响应 SIGTERM 或 SIGINT。我不知道是什么原因造成的。
看门狗.py
class watchdog:
# <snip> various init stuff
def start(self):
self.running = true
kids = ['app1', 'app2', 'app3', 'app4', 'app5', 'app6', 'app7']
self.processes = {}
for kid in kids:
self.start_child(kid)
self.thread = threading.Thread(target=self._monitor)
self.thread.start()
while self.running:
time.sleep(10)
def start_child(self, name):
try:
proc = subprocess.Popen(name)
self.processes[name] = proc
except:
print "oh no"
else:
print "started child ok"
def _monitor(self):
while self.running:
time.sleep(1)
if self.running:
for kid, proc in self.processes.iteritems():
if proc.poll() is not None: # process ended
self.start_child(kid)
所以发生的事情是 watchdog.start() 启动所有 7 个进程,如果我发送任何进程 SIGTERM,它就会结束,监控线程会再次启动它。但是,如果我随后发送新进程 SIGTERM,它会忽略它。
我应该能够一遍又一遍地向重新启动的进程发送 kill -15。为什么重启后就不管了?
最佳答案
如此处解释:http://blogs.gentoo.org/agaffney/2005/03/18/python_sucks ,当 Python 创建一个新线程时,它会阻止该线程的所有信号(以及该线程产生的任何进程)。
我使用通过 ctypes 调用的 sigprocmask 修复了这个问题。这可能是也可能不是“正确”的方法,但它确实有效。
在子进程中,在 __init__
期间:
libc = ctypes.cdll.LoadLibrary("libc.so")
mask = '\x00' * 17 # 16 byte empty mask + null terminator
libc.sigprocmask(3, mask, None) # '3' on FreeBSD is the value for SIG_SETMASK
关于Python 进程在重启后停止响应 SIGTERM/SIGINT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1133693/
脚本1.sh: #!/bin/bash ./script2.sh echo after-script 脚本2.sh: #!/bin/bash function handler { exi
我正在编写一个多线程程序,我想在其中处理来自用户的可能的 Ctrl-C 命令以终止执行。据我所知,不能保证能够取消每个工作线程的主线程会捕获信号。因此,是否有必要为工作线程的代码设置一个不同的信号处理
我正在编写一个多线程程序,我想在其中处理来自用户的可能的 Ctrl-C 命令以终止执行。据我所知,不能保证能够取消每个工作线程的主线程会捕获信号。因此,是否有必要为工作线程的代码设置一个不同的信号处理
标题说明了一切。我该如何处理或捕捉 SIGINT在 Julia ?从文档中我假设我只是想 catch InterruptException使用 try/catch像下面这样块 try whil
以下是此问题的简单重现: void handler(int sig){ if(sig == SIGINT){ printf("Signal caught
鉴于此代码: #include #include #include void sigint_handler(int h) { printf("Hey! I caught a SIGINT
我正在写一个shell,现在它来控制子进程。当我在子进程中使用 signal (SIGTERM, SIG_DFL); 时, 信号 SIGINT 由 Ctrl + C 生成,该信号终止整个操作系统 sh
我正在尝试 SIGINT。我基本上希望我的程序在用户按下 control-c 时立即启动。当这种情况发生时,我将让程序制作一个管道。 现在,我决定当在信号处理程序中按下 control-c 时,它将调
我想处理来自内核的 SIGINT 信号,以便调用一个函数来优雅地关闭我的进程。 这是一个工作示例,一个线程正在等待信号,然后调用函数 handle_stop: #include #include
我有一个 bash 脚本,它启动了 2 个进程: openocd ...flags... 2>openocd.log & arm-none-eabi-gdb 在 gdb 中,使用 Ctrl+C 中断执
我有几个带有 while read line 循环的脚本,当我按下 Ctrl C 时,它们不执行我的清理功能。例如: #!/bin/bash cleanup() { stty echo exi
我想捕获从 Script-A.sh 发送到 Script-B.sh 的信号所以在 Script-A.sh 中我使用命令: (Send SIGINT to Script-B.sh) kill -2 $P
我正在尝试处理 SIGINT。 SIGINT 在我的程序中的主要目的是取消当前搜索功能并打印当前可用的结果。但是每当我 try catch SIGINT 信号时,它都会关闭我的程序。 (我搜索了这么多
我有 2 个程序(由我编写)。第一个名为“MAN”的进程将调用“D”(第二个),这是一个将在后台运行直到以某种方式终止的进程。 我想在不终止 D 的情况下终止 MAN。 我尝试使用 ctrl + c
我应该编写一个 C 程序来处理第一个带有自定义处理程序的 SIGINT,然后重置默认行为。我的自定义 SIGINT 处理程序应该只打印一条消息。这是我写的: #include #include #
如果父进程接收到 ctrl-C 信号,我一直试图阻止我的父线程杀死子进程。我已经没有想法了。 父进程已经捕捉到 SIGINT,所以我想要和现在 child 死了一样。 int main() {
我对Python很陌生,所以如果这个问题非常基本,请原谅我。 我试图在使用选择模块从套接字接受数据时处理键盘中断。因此,我有一个 select.select() 函数调用来等待来自套接字的数据,然后将
我无法理解为什么我的 SIGINT 从未被下面的代码捕获。 #!/usr/bin/env python from threading import Thread from time import sl
我正在编写以下代码。该程序应该能够使用 sigaction 处理 SIGINT。到目前为止,它几乎完成了,但我遇到了两个问题。 第一个问题是如果程序在 3 秒内收到 3 个信号,它应该打印“正在关闭”
在 C 中,我想捕获 SIGINT 信号并打印出类似这样的消息通过使用 sigaction 并通过 向其传递新的处理程序来“接收到 SIGINT” sa.sa_sigaction = handler;
我是一名优秀的程序员,十分优秀!