Nginx 소스 코드 | Nginx 신호 처리

4077 단어
개술
최근 에 Nginx 소스 코드 를 보고 있 는데, ngx 를 보고 있 습 니 다.master_process_cycle () 함수, 이 함수 에서 신호 처 리 를 사 용 했 습 니 다.다음은 발췌:
    ...
    sigset_t           set;
    ...
    sigemptyset(&set);
    sigaddset(&set, SIGCHLD);
    sigaddset(&set, SIGALRM);
    sigaddset(&set, SIGIO);
    sigaddset(&set, SIGINT);
    sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));

    if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "sigprocmask() failed");
    }

    sigemptyset(&set);
    ...
    for( ;;){
      ...
      sigsuspend(&set);
      ...
    }
    ...

이 코드 는 나 로 하여 금 몇 가지 문 제 를 가지 게 한다.
  • 각 함수 의 작용 은 무엇 입 니까?
  • 어떻게 신 호 를 받 습 니까?어디서 이 루어 집 니까?
  • 왜 sigaddset 에 이 어 sigemptiset 까지?

  • 몇 가지 문제 의 해답
    각 함수 의 작용 은 무엇 입 니까?
    이 문 제 는 제 글 에 있 습 니 다. Nginx 소스 코드 | ngxmaster_process_cycle () 함수 중의 '보충' 부분 에 설명 이 있 습 니 다.
    어떻게 신 호 를 받 습 니까?어디서 이 루어 집 니까?
    처음에 나 도 신 호 를 받 는 코드 를 찾 고 있 었 다.프로 세 스 가 sigsuspend (& set) 함수 에 걸 렸 을 때 set 가 새로운 신 호 를 받 은 상태 에서 깨 어 날 수 있 기 때 문 입 니 다. 하지만 언제 set 에 새로운 신호 가 있 을 수 있 습 니까?그리고 나 서 나 는 ngx 에 들 어 갔다.process. c 파일, ngx 찾 았 습 니 다.int_t ngx_init_signals(ngx_log_t *log):
    ngx_int_t
    ngx_init_signals(ngx_log_t *log)
    {
        ngx_signal_t      *sig;
        struct sigaction   sa;
    
        for (sig = signals; sig->signo != 0; sig++) {
            ngx_memzero(&sa, sizeof(struct sigaction));
    
            if (sig->handler) {
                sa.sa_sigaction = sig->handler;
                sa.sa_flags = SA_SIGINFO;
    
            } else {
                sa.sa_handler = SIG_IGN;
            }
    
            sigemptyset(&sa.sa_mask);
            if (sigaction(sig->signo, &sa, NULL) == -1) {
    #if (NGX_VALGRIND)
                ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                              "sigaction(%s) failed, ignored", sig->signame);
    #else
                ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                              "sigaction(%s) failed", sig->signame);
                return NGX_ERROR;
    #endif
            }
        }
    
        return NGX_OK;
    }
    

    이 함 수 는 sigaction () 함 수 를 사 용 했 습 니 다.
    int sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
    

    그리고 struct sigaction 구조 체.
        stuct sigaction  
        {  
              void (*)(int) sa_handle;  
              sigset_t sa_mask;  
              int sa_flags;  
        }  
    

    기능:
  • 신호 처리 방식 을 조회 하거나 설정 하고 특정한 신호 의 처리 함 수 를 설정 합 니 다.

  • sa_mask, 신호 차단 집합 은 함수 sigemptyset / sigaddset 등 을 통 해 차단 해 야 할 신 호 를 비우 고 추가 할 수 있 습 니 다. 위의 코드 에서 신호 SIGINT 를 처리 할 때 SIGQUIT 신 호 를 보 내 면 차단 되 지만 SIGQUIT 를 처리 하고 SIGINT 가 오 면 먼저 SIGINT 를 처리 한 다음 에 SIGQUIT 를 처리 합 니 다.

  • sa_flags 값 이 0 이면 기본 동작 을 표시 합 니 다.다음 과 같은 두 가 지 를 취 할 수 있 지만, 나 는 이 두 가치 가 무슨 소 용이 있다 고 생각 하지 않 는 다.SA_NODEFER, 이 플래그 를 설정 하면 현재 처리 신 호 를 차단 SA 로 하지 않 습 니 다.RESETHAND, 이 플래그 가 설정 되 어 있 으 면 현재 신 호 를 처리 한 후 신호 처리 함 수 를 SIG 로 설정 합 니 다.DFL 행위
  • sa_handle 은 신호 처리 함수 로 신호 가 올 때 이 신호 처리 함 수 를 호출 하여 신 호 를 처리 합 니 다.따라서 수신 신 호 는 ngxint_t ngx_init_signals (ngx log t * log) 함수 에서 실 현 된 것 은 sigaction 과 siguspend 를 결합 하여 신호 체 제 를 실현 합 니 다.


  • 왜 sigaddset 에 이 어 sigemptiset 까지?
    siguspend (& set) 함 수 는 set 에 새로운 신호 가 있어 야 깨 어 납 니 다. 그래서 처음에 sigaddset 함수 로 모든 신 호 를 set 에 추가 한 다음 sigprocmask 로 마스크 설정 을 하고 set 의 신호 마스크 를 현재 신호 마스크 에 추가 합 니 다. 신호 마스크 를 설정 하면 set 는 비 워 집 니 다. 그리고 siguspend 함 수 를 호출 합 니 다. 비 워 지지 않 으 면...신 호 를 받 아 도 프로 세 스 를 깨 우지 않 습 니 다. set 에 있 는 모든 신호 가 있 기 때문에 받 은 모든 신 호 는 새로운 신호 가 아니 기 때문에 프로 세 스 를 깨 우지 않 습 니 다.

    좋은 웹페이지 즐겨찾기