【问题标题】:IPC notify a process to change parametersIPC 通知进程更改参数
【发布时间】:2025-12-26 12:50:11
【问题描述】:

我创建了一个将数据从源目录复制到目标目录的守护进程。

我将其命名为cpd(复制守护进程)。它定期运行此cp 命令:cp src dest

但是如果我需要改变这个cp命令执行的间隔,我应该如何与cpd守护进程通信呢?

例如:cpd -p 120 --> 其中-p 表示句点,120 以秒为单位。

PS:“我知道如何启动后台进程:创建子进程并退出父进程, 设置新的会话 id,关闭继承的标准文件描述符,更改工作目录。创建守护进程的标准步骤。我还使用syslog 在每个命令执行后记录状态消息。”

Reference for daemon creation

@保罗: 所以我需要一个像下面这样的配置文件。当我在没有-d 选项的情况下运行时,我应该向守护进程发出信号以读取此文件并相应地更改其变量和行为。对吗?

# Example configuration file for cpd - An test Linux daemon.
# Comments start with a # and are ignored.
# Configuration options are delimited by = and ;
# Example:
#    arg=val;
verbose_logging_enabled=true;
daemon_enabled=false;
config_file_path=/etc/cpd.conf;
source_path=/home/Documents/Source;
destination_path=/home/Documents/Destination;

【问题讨论】:

  • 所以你基本上是在问,“一个程序如何在 Linux 下与另一个程序通信?”一些常用的方法是文件、命名管道、套接字、信号。例如,inetd 在收到 SIGHUP 时会重新读取其配置文件。
  • 您很可能需要更多代码,但您不必将它放在单独的程序中。单个程序可以有一个带有 if args contain "-d" then call run_daemon(args) else call send_to_daemon(args) 的主程序。问题是您需要编写run_daemon()send_to_daemon() 并决定协议的所有细节。
  • 没关系。现在,如果您查看目录 /var/run,您可能会发现一些其他守护进程留下的 pid 文件。这些文件包含一个数字,即正在运行的守护程序的进程 ID 号。通过创建/读取/写入该文件,您的命令行进程可以知道守护进程的 pid,或者是否有一个正在运行。这就是命令行进程如何知道向哪个 pid 发送信号、让守护进程读取其配置文件或以其他方式检查其“收件箱”的方式。如果你想使用套接字,你必须使用像 select() 这样更难的异步调用。

标签: linux unix terminal


【解决方案1】:

这取决于您希望与正在运行的守护程序进行多少通信。

如果您想进行完整的对话,那么您将不得不考虑套接字、侦听器和协议等等。这是相当多的工作。

不过,您的要求听起来很简单。在这种情况下,常规的做法是让您的守护进程为HUP 安装一个信号处理程序(请参阅sigaction 或您的unix 风格的等效项)。当程序接收到该信号时,处理程序只需重新读取配置文件(或者更确切地说,执行一些导致守护程序以某种方式重新读取该配置文件的操作)。因此顺序是:

% vi .../my-daemon.config
% kill -HUP <daemon-pid>

让守护进程在启动时将其 PID 写入/var/run 中的文件是很常见的,因此第二行将是

% kill -HUP `cat /var/run/mydaemon.pid`

如果您想实现并自动化,那么您可以向守护程序添加一些选项,该选项会更改配置,然后发送信号(请参阅kill(2))。

还有一点是USR1USR2 信号是用于这种通信的。如果您为HUPUSR1USR2 安装信号处理程序,那么您可以对您的守护程序进行三种不同类型的poke。这可能就是您所需要的。

【讨论】:

    【解决方案2】:

    您可以让您的进程监听 SIGUSR1 和 SIGUSR2(用户定义的信号)。在 SIGUSR1 上,它将复制间隔增加一些预定义的值,在 SIGUSR2 上,它减少它。你很容易做到这一点:

    //call at startup
    signal(SIGUSR1, SIGUSR1Handler);
    signal(SIGUSR2, SIGUSR2Handler);
    
    //handlers:
    void  SIGUSR1Handler(int sig)
    {
        //increment copy interval
        //maybe print a message with the new value
    }
    
    void  SIGUSR2Handler(int sig)
    {
        //increment copy interval
        //maybe print a message with the new value
    }
    

    这与其他人已经提到的与守护进程通信的方式实际上没有什么不同,但增加了一点实用的方面,即不需要任何外部配置。

    【讨论】:

    • hi @xpa1492 自定义信号处理程序意味着只允许预定义的间隔。但我希望指定用户传递的确切值。因此,我认为 SIGHUP 解决方案现在是可以接受的
    【解决方案3】:

    如果您的守护进程大部分时间无事可做,为什么不让它执行“阻塞”读取()?即等到文件充满命令然后读取它。命令行可以只是一个写入命令文件的脚本。

    【讨论】:

    • 好吧,这与我的守护进程是否有用,标准方法会更好,我也会了解它。