摘錄nginx 訊號處理方法部分程式碼

hai0808發表於2017-11-27

編譯及執行步驟:

  • 1.接收程式編譯 : g++ -g -o a.out signal.c
  • 2.執行接收程式:./a.out
  • 3.傳送程式編譯: g++ -o b.out signal.c
  • 4.傳送程式查詢接收程式pid:ps -alx | grep a.out | awk ‘{print $3}’
  • 5.傳送程式傳送訊號:./b.out -s reload -p 36357(36357是第4部查詢到的程式PID號)
    說明:nginx把主程式號寫入檔案中,在本例中手動查詢下,當引數傳入b.out程式

程式碼塊

#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include <signal.h> 
#include <unistd.h>
#define ngx_memzero(buf, n)       (void) memset(buf, 0, n)  //ngx_memzero使用的是memset原型,memset使用匯編進行編寫
void
ngx_signal_handler(int signo)
{
printf("ngx_signal_handler :%d\n", signo);
}
typedef struct {
    int     signo;  //訊號的編號
    char   *signame; //訊號的字串表現形式
    char   *name; //訊號名稱
    void  (*handler)(int signo); //訊號處理函式
} ngx_signal_t;

#define ngx_signal_helper(n)     SIG##n
#define ngx_signal_value(n)      ngx_signal_helper(n)

#define ngx_random               random

/* TODO: #ifndef */
#define NGX_SHUTDOWN_SIGNAL      QUIT
#define NGX_TERMINATE_SIGNAL     TERM
#define NGX_NOACCEPT_SIGNAL      WINCH
#define NGX_RECONFIGURE_SIGNAL   HUP

#if (NGX_LINUXTHREADS)
#define NGX_REOPEN_SIGNAL        INFO
#define NGX_CHANGEBIN_SIGNAL     XCPU
#else
#define NGX_REOPEN_SIGNAL        USR1
#define NGX_CHANGEBIN_SIGNAL     USR2
#endif

#define ngx_value_helper(n)   #n
#define ngx_value(n)          ngx_value_helper(n)

ngx_signal_t  signals[] = {
    { ngx_signal_value(NGX_RECONFIGURE_SIGNAL),
      "SIG" ngx_value(NGX_RECONFIGURE_SIGNAL),
      "reload",
      ngx_signal_handler
    },

    { ngx_signal_value(NGX_REOPEN_SIGNAL),
      "SIG" ngx_value(NGX_REOPEN_SIGNAL),
      "reopen",
    },

    { ngx_signal_value(NGX_NOACCEPT_SIGNAL),
      "SIG" ngx_value(NGX_NOACCEPT_SIGNAL),
      "",
      ngx_signal_handler 
    },

    { ngx_signal_value(NGX_TERMINATE_SIGNAL),
      "SIG" ngx_value(NGX_TERMINATE_SIGNAL),
      "stop",
      ngx_signal_handler 
    },

    { ngx_signal_value(NGX_SHUTDOWN_SIGNAL),
      "SIG" ngx_value(NGX_SHUTDOWN_SIGNAL),
      "quit",
      ngx_signal_handler
    },

    { ngx_signal_value(NGX_CHANGEBIN_SIGNAL),
      "SIG" ngx_value(NGX_CHANGEBIN_SIGNAL),
      "",
      ngx_signal_handler
    },

    { SIGALRM, "SIGALRM", "", ngx_signal_handler },

    { SIGINT, "SIGINT", "", ngx_signal_handler },

    { SIGIO, "SIGIO", "", ngx_signal_handler },

    { SIGCHLD, "SIGCHLD", "", ngx_signal_handler },

    { SIGSYS, "SIGSYS, SIG_IGN", "", SIG_IGN },

    { SIGPIPE, "SIGPIPE, SIG_IGN", "", SIG_IGN },

    { 0, NULL, "", NULL }
};


int ngx_os_signal_process(char *name, int pid)
{
    ngx_signal_t  *sig;


    for (sig = signals; sig->signo != 0; sig++) {
        if (strcmp(name, sig->name) == 0) {
            printf("send signame: %s\n", name);
            if (kill(pid, sig->signo) != -1) {
                return 0;
            }
           printf("ngx_os_signal_process");
        }
    }
    return 1;
}

bool ngx_init_signals()
{
    ngx_signal_t      *sig;
    struct sigaction   sa;
    for (sig = signals; sig->signo != 0; sig++) {
        ngx_memzero(&sa, sizeof(struct sigaction));
        sa.sa_handler = sig->handler;
        sigemptyset(&sa.sa_mask);
        if (sigaction(sig->signo, &sa, NULL) == -1) {
            printf("sigaction(%s) failed", sig->signame);
            return false;
        }
    }
    return true;
}
unsigned int process;
static char *csignal;
int pid = 0;
int main(int argc, char *const *argv)
{
    u_char *p;
    int i;
    for (i = 1; i < argc; i++)
    {
        p = (u_char*) argv[i];
        if(*p++ != '-')
        {
            printf("invalid option: - !\n");
            return -1;
        }
        while(*p)
        {
            switch(*p++)
            {
        case 's':
        case 'S':
            if(*p)
            {
                csignal = (char*)p;
                printf("p csignal:%s\n", csignal);
            }
            else if(argv[++i])
            {
                csignal = argv[i];
                printf("argv csignal:%s\n", csignal);
            }
            else
            {
                printf("case s error!\n");
                return -1;
            }

            if(strcmp(csignal, "reload") == 0)
            {
                printf("reload\n");
                continue;
            }
            else
            {
                printf("not reload\n");
                return -1;
            }
            break;
        case 'p':
            {
                pid = atoi(argv[++i]);
            }
            break;
        default:
            printf("default err!\n");
            return -1;

            }
        }
    }
    if(csignal)
    {
        if(pid == 0)
        {
            printf("pid : 0\n");
            return 0;
        }
        printf("pid: %d\n", pid);
        ngx_os_signal_process(csignal, pid);
        printf("run csignal!");
        return 0;
    }
    ngx_init_signals();
    while(1)
    {
        printf("main\n");
        sleep(1);
    };
}

相關文章