如何在 Linux 中重新启动(或重置)正在运行的进程

如何在 Linux 中重新启动(或重置)正在运行的进程

我有两个通过套接字进行通信的 Linux 系统(桌面和基于 ARM 的开发板)。

当服务器发送特定的预定义消息时,我想重新启动(或重置)我的客户端应用程序(在开发板上运行)。我不想重新启动(重新启动)Linux,我只想让客户端应用程序自动重新启动。

我无法理解应该如何做。

答案1

/proc/self/exe让您的客户端在收到该特定消息时执行。您不需要知道可执行文件实际驻留在文件系统中的位置。您可以重用main()'sargv来构造新的参数向量。

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
        char buf[32] = {};
        char *exec_argv[] = { argv[0], buf, 0 };
        int count = argc > 1 ? atoi(argv[1]) : 0;

        printf("Running: %s %d\n", argv[0], count);
        snprintf(buf, sizeof(buf), "%d", count+1);
        sleep(1);

        execv("/proc/self/exe", exec_argv);

        /* NOT REACHED */
        return 0;
}

restart.c运行起来是这样的:

$ gcc restart.c 
$ ./a.out 3
Running: ./a.out 3
Running: ./a.out 4
Running: ./a.out 5

答案2

执行此操作的正常方法是让程序退出,然后使用监视系统重新启动它。这init程序提供了这样一个监控系统。有许多不同的 init 程序(SysVinit、BusyBox、Systemd 等),具有完全不同的配置机制(总是编写配置文件,但文件的位置和语法不同),因此请查找您所使用的初始化程序的文档正在使用。配置 init 以在启动时或根据明确请求启动您的程序,并在程序终止时重新启动它。还有更高级的监控程序,但听起来您并不需要它们。与让程序自行重新启动相比,这种方法有很多优点:它是标准的,因此您可以重新启动一堆服务,而不必关心它们是如何制作的;即使程序因错误而终止,它仍然可以工作。

有一个标准机制可以告诉进程退出:信号。向您的程序发送 TERM 信号。如果您的程序需要执行任何清理,请编写一个信号处理程序。如果您有一个管理通道向它发送这样的命令,这并不排除使用特定于程序的命令来关闭它。

答案3

如果客户端应用程序是 Linux 服务,则可以使用以下命令重新启动它:

service <clientapp> restart

或强制重新加载其配置:

service <clientapp> reload
service <clientapp> force-reload

如果它更可能是自定义应用程序,则需要在其代码中嵌入在接收到信号或事件时重新启动或重新加载其配置的功能。如果不这样做,作为最后的手段,你可以随时终止客户端应用程序:

pkill -9 <clientapp>

并再次重新启动,但这很丑陋,因为它使应用程序处于不确定状态。

答案4

有时,一个进程会挂起,尽管它看起来正在运行,但实际上并没有执行任何操作,这可能是由于偶尔触发的代码错误所致。唯一能做的就是重新启动,但这意味着首先找到并杀死挂起的进程。

我遇到一个问题,一个进程(Python 服务器)不时挂起而不退出。我通过每隔几个小时强制终止/重新启动来处理它。这是由cron;调用的脚本有问题的程序是myapp.py.奇怪的grep是阻止grep返回它自己的进程ID。

#!/bin/sh

# This cron script restarts the server
# Look for a running instance of myapp.py
p=$(ps -eaf | grep "[m]yapp.py")
# Get the second item; the process number
n=$(echo $p | awk '{print $2}')
# If it's not empty, kill the process
if [ "$n" ]
then
   kill $n
fi
# Start a new instance
python3 myapp.py

相关内容