簡體   English   中英

如何在收到SIGHUP信號后在Linux中重啟C守護程序

[英]How to restart C daemon program in Linux after receiving SIGHUP signal

任何人都可以發布一些示例代碼,說明如何在守護程序收到SIGHUP信號后重新讀取配置文件並重啟我的守護程序。 守護進程是在Linux上用C編寫的用戶空間程序,不是由inetd啟動的。

根據您的程序編寫的干凈程度,有(至少)三種方法:

  1. 收到信號后,在初始化階段之前(可能 - 但不一定 - 通過setjmp()/ longjmp()或sigsetjmp()/ siglongjmp()對)返回程序的開頭,從而重置並重新讀取配置文件。

  2. 收到信號后,讓信號處理程序再次執行原始程序。 這具有丟失所有狀態並將所有全局變量和靜態變量重置回其原始狀態的優點。 它有失去所有以前的狀態的缺點。

  3. 第三種選擇可能不那么殘酷; 它會注意到信號已被接收,並且在主處理循環中的下一個方便點,將返回並重新讀取配置文件。

什么工作取決於你的守護進程必須做什么。 如果它花時間與客戶進行對話,您可能不想使用選項1或2中的任何一個 - 您更願意使用選項3.如果您對簡單問題做一次性回答,那么殘酷的方法可能是有效(並且可能更容易編程)。 請注意,選項1需要仔細處理WIP(正在進行的工作)和諸如打開文件之類的事情 - 如果您不小心,您將失去對資源的跟蹤,並且守護程序將失敗(內存不足,文件描述符之外 - 最有可能是這兩個中的一個)。

我找到了這個頁面,因為我自己正在尋找一個例子,以確保我正確地做到了。 由於沒有這方面的例子,我會發布我的嘗試並讓其他人評論它:

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;
}

取決於你如何構建它; 如果您在單個線程/進程中處理多個連接,那么在重新加載配置(或exec本身)之前,您應該以某種方式通知它們退出(如果可以;依賴於協議)。

如果協議允許你說“離開並稍后回來”,那么顯然這樣做是一個很好的勝利。 如果客戶端需要保持連接,則可以將配置更改應用於已連接的客戶端(如果它是單進程單線程守護程序,如果這是有意義的話)。

如果它是多個過程,事情變得更加復雜。 您必須通知進程有關新配置,或確保它們繼續使用舊配置,或者他們可以在客戶端退出時選擇新配置。

如果它是多線程,線程將需要安全地能夠在它們正在進行的任何事情中讀取新配置,這可能需要鎖定,或者您可以為新的配置結構分配內存並進行切換不知何故,

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM