2010-06-02 77 views
7

任何人都可以发布一些示例代码,告诉我如何重新读取配置文件并在守护进程收到SIGHUP信号后重新启动守护进程。守护进程是在Linux上用C语言编写的用户空间程序,不是由inetd启动的。如何在接收到SIGHUP信号后在Linux中重新启动C守护进程程序

+6

人们通常不希望守护进程在接收SIGHUP时重新启动,但它们会进行优雅的重新加载,即加载新的配置文件,但不会丢失连接的Cliens和类似的坏东西。 – ThiefMaster 2010-06-02 08:06:16

回答

5

取决于你的程序是如何干净地写,有(至少)三种方式来做到这一点:

  1. 在收到信号后,返回到程序的开始,在初始化阶段之前(可能 - 但不一定 - 通过setjmp()/ longjmp()或sigsetjmp()/ siglongjmp()对),从而重置和重新读取配置文件。

  2. 收到信号后,让信号处理程序再次执行原始程序。这具有失去所有状态并将所有全局变量和静态变量重置为原始状态的优点。它有失去以前所有状态的缺点。

  3. 第三个选择也许不那么残忍,它会注意到信号已经被接收,并且在主处理循环的下一个方便的位置,将返回并重新读取配置文件。

什么作品取决于你的守护进程的功能。如果花费时间与客户进行对话,则可能不想使用选项1或2中的任何一个 - 您更愿意使用选项3.如果您对简单问题进行一次性回答,那么残酷的方法可能是有效(并且可能更易于编程)。请注意,选项1需要仔细处理WIP(正在进行中的工作)以及诸如打开文件之类的内容 - 如果您不小心,将会丢失资源跟踪,并且守护程序将失败(内存不足,文件描述符不足 - 最有可能是这两个之一)。

0

取决于你如何构造它;如果你在单个线程/进程中处理多个连接,那么在重新加载配置(或exec本身)之前,你应该以某种方式通知他们退出(如果可以,取决于协议)。

如果协议允许你说“离开并稍后再回来”,那么清楚地做到这一点是一个很好的胜利。如果客户端需要保持连接状态,那么可以将配置更改应用到已连接的客户端(如果它是单进程单线程守护进程),这是否合理。

如果是多进程,事情会变得更加复杂。您必须通知流程有关新配置,或确保它们继续使用旧配置,或者在客户端退出时可以选择新配置。

如果它是多线程,那么线程需要安全地读取新配置,无论他们正在做什么,可能需要锁定,或者您可以为新配置结构分配内存,并执行切换不知何故,

1

我发现这个页面,因为我正在寻找一个自己的例子,以确保我做得正确。由于对此没有例子,我会后我的努力,让上评论他人:

volatile sig_atomic_t g_eflag = 0; 
volatile sig_atomic_t g_hupflag = 1; 

static void signal_handler(int sig) 
{ 
    switch(sig) 
    { 
    case SIGHUP: 
     g_hupflag = 1; 
     break; 
    case SIGINT: 
    case SIGTERM: 
     g_eflag = 1; 
     break; 
    } 
} 

int main(int argc, char **argv) 
{ 
    signal(SIGINT, signal_handler); 
    signal(SIGTERM, signal_handler); 
    signal(SIGHUP, signal_handler); 
    signal(SIGPIPE, SIG_IGN); 

    while(!g_eflag) 
    { 
     if(g_hupflag) 
     { 
      g_hupflag = 0; 
      load_config(); 
     } 

     // ... do daemon work ... 
    } 

    return 0; 
}