2010-06-02 29 views
7

Ai đó có thể đăng một số mã ví dụ về cách tôi có thể đọc lại tập tin cấu hình và khởi động lại daemon sau khi daemon nhận tín hiệu SIGHUP. Daemon là một chương trình không gian người dùng được viết bằng C trên Linux và không được bắt đầu bằng inetd.Cách khởi động lại chương trình C daemon trong Linux sau khi nhận được tín hiệu SIGHUP

+6

Mọi người thường không mong đợi daemon khởi động lại khi nhận SIGHUP nhưng chúng thực hiện tải lại duyên dáng, tức làtải tập tin cấu hình mới nhưng không làm rơi những người bị kết nối và những thứ xấu tương tự. – ThiefMaster

Trả lời

5

Tùy thuộc vào cách sạch chương trình của bạn được viết, có (ít nhất) ba cách để làm điều đó:

  1. Khi nhận được tín hiệu, trở về sự bắt đầu của chương trình, trước khi giai đoạn khởi (có thể - nhưng không nhất thiết - thông qua cặp setjmp()/longjmp() hoặc sigsetjmp()/siglongjmp()), do đó đặt lại và đọc lại tệp cấu hình.

  2. Khi nhận tín hiệu, hãy yêu cầu trình xử lý tín hiệu thực hiện lại chương trình gốc. Điều này có giá trị của việc mất tất cả các tiểu bang và đặt lại tất cả các globals và biến tĩnh trở lại trạng thái ban đầu của họ. Nó có khả năng mất tất cả trạng thái trước đó.

  3. Tùy chọn thứ ba ít tàn bạo hơn, có lẽ; nó sẽ lưu ý rằng tín hiệu đã được nhận và tại điểm thuận tiện tiếp theo trong vòng lặp xử lý chính, sẽ quay trở lại và đọc lại tệp cấu hình.

Điều gì hoạt động phụ thuộc một phần vào những gì daemon của bạn phải làm. Nếu nó dành thời gian trong một cuộc trò chuyện với khách hàng, bạn có thể không muốn sử dụng một trong các tùy chọn 1 hoặc 2 - bạn muốn sử dụng tùy chọn 3. Nếu bạn đang thực hiện một câu trả lời cho các câu hỏi đơn giản, các cách tiếp cận tàn bạo có thể hiệu quả (và có lẽ đơn giản hơn để lập trình). Lưu ý rằng tùy chọn 1 yêu cầu xử lý cẩn thận WIP (công việc đang tiến hành) và những thứ như mở tệp - nếu bạn không cẩn thận, bạn sẽ mất nguồn tài nguyên và daemon sẽ không thành công (hết bộ nhớ, ngoài bộ mô tả tệp) rất có thể là một trong hai).

0

Phụ thuộc vào cách bạn cấu trúc nó; nếu bạn xử lý nhiều kết nối trong một luồng/quy trình, thì có lẽ bạn nên thông báo cho chúng để thoát (nếu bạn có thể; phụ thuộc vào giao thức) trước khi tải lại cấu hình (hoặc chính bản thân exec).

Nếu giao thức cho phép bạn nói "biến mất và quay lại sau", thì việc làm rõ ràng đó là một chiến thắng tốt. Nếu khách hàng cần duy trì kết nối, bạn có thể áp dụng các thay đổi cấu hình cho các máy khách đã được kết nối, nếu đó là một daemon một quy trình đơn, nếu điều đó có ý nghĩa.

Nếu đó là quá trình đa, mọi thứ trở nên phức tạp hơn. Bạn sẽ phải thông báo cho các quy trình về cấu hình mới, hoặc đảm bảo rằng chúng tiếp tục với cấu hình cũ hoặc có thể chọn cấu hình mới khi khách hàng của họ thoát.

Nếu nó là chủ đề đa, các chủ đề sẽ cần một cách an toàn có thể đọc cấu hình mới ở giữa bất cứ điều gì họ đã làm, có thể cần khóa, hoặc bạn có thể cấp phát bộ nhớ cho cấu trúc cấu hình mới và chuyển đổi theo cách nào đó,

1

Tôi tìm thấy trang này vì tôi đang tìm kiếm một ví dụ để đảm bảo rằng tôi đang thực hiện chính xác. Vì không có ví dụ cho điều này tôi sẽ đăng nỗ lực của tôi và để người khác nhận xét về nó:

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; 
} 
Các vấn đề liên quan