【发布时间】:2020-03-15 08:29:50
【问题描述】:
我想要一种方便的方法来重新启动程序。我以为我可以捕获一个信号(示例中为 USR1)并调用 exec。
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
char* const* args;
void restart() {
printf("restarting\n");
execv(args[0], args);
}
int main(int argc, char* const argv[]) {
printf("Starting\n");
args = argv;
signal(SIGUSR1, restart);
raise(SIGUSR1); // could use pkill -SIGUSR1 file-name instead
pause();
printf("Terminated normally\n");
return 0;
}
上面的例子有点工作。输出是
Starting
restarting
Starting
然后挂起。仍然可以接收其他信号。
我想我只是没能清除信号。预期的行为是程序无限期地重新启动。
【问题讨论】:
-
printf()不保证是异步信号安全的。不要从信号处理程序中调用它。安全功能列表在这里:man7.org/linux/man-pages/man7/signal-safety.7.html -
有没有想过使用 setjmp 和 longjmp?将jmp设置为程序的开头,当您收到信号时,将longjmp设置为程序的开头。这样,每次获得 SIGUSR1 时,您只会在内存中拥有一个进程,而不是一个新进程。
-
@cup:也许,但这不会重新启动程序。无论如何,它不会改变 OP 的问题;处理程序仍然不会触发第二次。
-
raise()不会生成异步信号——但在信号处理程序中使用printf()仍然不是一个好主意。见:How to avoid usingprintf()in a signal handler?