Author: PO
Link: http://blog.csdn.net/livelylittlefish/article/details/7308100
Content
0. Preface
1. Ngx_init_signals () function
1.1 ngx_signal_t Structure
1.2 Signals array
1.3 Sigaction Structure
2. A few questions
How the 2.1ngx_signal_value macro gets the signal value of the integer signo.
2.2 handler=sig_ign=0x1 is how to ignore the signal.
3.ngx_signal_handler () function
4. Summary
0. Preface
This paper mainly analyzes the initialization of nginx signal and its processing. If there is no special description in the article, the nginx-1.0.4 code directory is/usr/src/nginx-1.0.4.
1. Ngx_init_signals () function
The main task of this function is to set the action of each signal in the signals[] array (that is, the usual registration, installation, etc.). As follows.
./src/os/unix/ngx_process.c
ngx_int_t
ngx_init_signals (ngx_log_t *log)
{
ngx_signal_t *sig;
struct sigaction sa;
for (sig = signals Sig->signo!= 0; sig++) { /* signals array
/Ngx_memzero (&sa, sizeof (struct sigaction)); * Here sigaction is a structural type * *
Sa.sa_handler = sig->handler;
Sigemptyset (&sa.sa_mask); /* Empty Sa_mask/
if (sigaction (Sig->signo, &sa, NULL) = = 1) {/* Set action for Sig->signo signal, here Sigaction as System API * /
ngx_log_error (Ngx_log_emerg, log, Ngx_errno,
"Sigaction (%s) failed", sig->signame);
Return Ngx_error
}
}
return NGX_OK;
}
1.1 ngx_signal_t Structure
The NGINX signal structure is as follows.
typedef struct {
int signo; /* Signal Value
* /char *signame; /* Signal name
* /char *name; /* Signal readable name * /Void (*handler) (int signo); /* Signal Processing program * *
ngx_signal_t;
The registered handler is executed when the Nginx process receives the relevant signal.
1.2 Signals array
For the signals array in the function, the handler of the signal is Ngx_signal_handler (), as shown below.
./src/os/unix/ngx_process.c
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_handler}, {Ngx_signal_value (ngx_noaccept_signal), "SIG" Ngx_value (N gx_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_sig NAL), "SIG" Ngx_value (ngx_changebin_signal), "", Ngx_signal_handler}, {sigalrm, "sigalrm", "", Ng
X_signal_handler}, {SIGINT, "SIGINT", "", Ngx_signal_handler}, {Sigio, "Sigio", "", Ngx_signal_handler}, {sigchld, "sigchld", "", Ngx_signal_handler}, {Sigsys, "Sigsys, Sig_ign", "", sig_ign},/* sigsys=31, the signal handler=sig_ign, indicating that the signal is ignored/ {sigpipe, "sigpipe, Sig_ign", "", sig_ign},/* sigpipe=13, the signal handler=sig_ign, indicating that the signal is ignored/{0, NULL, "", NULL }
};
By debugging Nginx, you can view the actual contents of the array in the running environment, as well as the ngx_signal_t structure, and the types of signals supported by Nginx. As follows.
(GDB) p signals $ = {{Signo = 1, Signame = 0x476235 "Sighup", name = 0x4726ab "Reload", Handler = 0x4
1df10 <ngx_signal_handler>}, {signo = ten, Signame = 0x47623c "SIGUSR1", name = 0X4726A4 "Reopen", Handler = 0x41df10 <ngx_signal_handler>}, {signo =, Signame = 0x476244 "Sigwinch", name =
0x47b68f "", Handler = 0x41df10 <ngx_signal_handler>}, {signo =, Signame = 0x47624d "Sigterm", Name = 0x47269a "Stop", handler = 0x41df10 <ngx_signal_handler>}, {signo = 3, Signame = 0x476
255 "Sigquit", name = 0x47269f "Quit", handler = 0x41df10 <ngx_signal_handler>}, {signo = 12, Signame = 0x47625d "SIGUSR2", name = 0x47b68f "", Handler = 0x41df10 <ngx_signal_handler>}, {sign o = Signame = 0x476265 "Sigalrm", name = 0x47b68f "", Handler = 0x41df10 <ngx_signal_handler>}
, {Signo = 2,Signame = 0x47626d "SIGINT", name = 0x47b68f "", Handler = 0x41df10 <ngx_signal_handler>}, {Signo
= Signame = 0x476274 "Sigio", name = 0x47b68f "", Handler = 0x41df10 <ngx_signal_handler>}, { Signo = Signame = 0x47627a "SIGCHLD", name = 0x47b68f "", Handler = 0x41df10 <ngx_signal_handler >}, {signo = Signame = 0x476282 "Sigsys, sig_ign", name = 0x47b68f "", handler = 0x1/* The signal handler=sig_ign=0x1, indicating that the signal is ignored/}, {signo = Signame = 0x476292 "Sigpipe, sig_ign", name = 0x47b68f "", Handler = 0x1/* The signal handler=sig_ign=0x1, indicating that the signal is ignored/}, {signo = 0, signame = 0x0, name = 0x 47b68f "", handler = 0}}
By debugging the contents of the signals array, you can see its definition very clearly. A few of the macros used are as follows.
./src/core/ngx_config.h
#define NGX_SIGNAL_HELPER (n) sig# #n
#define NGX_SIGNAL_VALUE (n) ngx_signal_helper (n)
#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
1.3 Sigaction Structure
The sigaction structure is defined as follows.
struct Sigaction {
void (*sa_handler) (int);
void (*sa_sigaction) (int, siginfo_t *, void *);
sigset_t Sa_mask;
int sa_flags;
void (*sa_restorer) (void);
This definition comes from the Sigaction manual page and may be adjusted for different versions if you view the kernel source code.
2. A few questions
How the 2.1ngx_signal_value macro gets the signal value of the integer signo.
For example, Ngx_reconfigure_signal=hup, so Ngx_signal_value (ngx_reconfigure_signal) =sighup.
From the above signals array, we can see that the signo=1,name of Sighup is "reload". So, where is this 1 defined?
-It's easy to think of kernel source code. Fruit not otherwise, in #include <signal.h>
Both file:/usr/include/asm/signal.h and/usr/include/asm-generic/signal.h are defined.
#define SIGHUP 1
#define SIGINT 2
#define SIGQUIT 3
#define Sigill 4
#define Sigtrap 5
#define SIGABRT 6
#define Sigiot 6
#define Sigbus 7
#define SIGFPE 8
#define SIGKILL 9
#define SIGUSR1
#define SIGSEGV
#define SIGUSR2
#define SIGPIPE
#define SIGALRM
#define SIGTERM
#define Sigstkflt
#define SIGCHLD
#define Sigcont
#define SIGSTOP
# Define SIGTSTP
#define Sigttin
#define Sigttou
#define Sigurg
#define SIGXCPU
#define SIGXFSZ
#define SIGVTALRM
#define SIGPROF 27
#define Sigwinch
#define Sigio
#define Sigpoll sigio/
*
#define Siglost
* *
#define SIGPWR
#define SIGSYS
#define sigunused This/
* should not is considered constants from Userland. * *
#define sigrtmin
#define SIGRTMAX _nsig
2.2 handler=sig_ign=0x1 is how to ignore the signal.
It can be seen from the above signals array that the sigsys=31 and sispipe=13 signals, their handler=sig_ign=0x1, indicate that the signal is ignored. is how to do it. where sig_ign is defined.
File:/usr/include/asm-generic/signal-defs.h
#ifndef sig_block
#define Sig_block 0/ * for blocking signals */
#endif
#ifndef sig_unblock
# Define Sig_unblock 1/ * for unblocking signals */
#endif
#ifndef sig_setmask
#define Sig_setmask 2 /* for setting the signal mask
/#endif #ifndef __assembly__
typedef void __signalfn_t (int );
typedef __signalfn_t __user *__sighandler_t;
typedef void __restorefn_t (void);
typedef __restorefn_t __user *__sigrestore_t;
#define SIG_DFL ((__force __sighandler_t) 0)/ * default signal handling/
#define SIG_IGN (__ Force __sighandler_t 1) /* Ignore signal
/#define SIG_ERR ((__force __sighandler_t)-1)/ * ERROR Return from Signal * *
#endif
That
#defineSIG_IGN ((Void (*) (int)) 1)
Its handler function type is void (*) (int) and conforms to the Sa_handler definition in the sigaction structure. Indicates that the signal ignores the function address of 1, whereas in practice it is not possible to have a function address of 1, so it can be distinguished from other pointers.
In fact, for Nginx Signal No. 31st and 13th, Sigaction will sig_ign=0x1 registration (registration) as its signal handler. The two signals are handed over to the system (init process) for processing.
Another: Ignore the sigchld signal, often as a skill to improve the performance of concurrent servers. Because the concurrent server may fork many child processes, the child processes end up needing the server process wait child process and clean up the resource. If this signal is omitted, the kernel can give the zombie process to the INIT process, saving a lot of the system resources that the zombie subprocess occupies.
3.ngx_signal_handler () function
The function is assigned to the corresponding global variables, such as Ngx_quit, Ngx_terminate, ngx_noaccept, and so on, according to the signal received, and the corresponding action is taken when the process finds that the corresponding variable is 1 o'clock.
The specific processing, can refer to the source code.
4. Summary
This paper mainly analyzes how the signal is initialized during the Nginx startup process.
Reference
# Mans Sigaction
# Man-s 7 Signal
# man-s 2 Kill
<unix Network Programming >
Http://www.cplusplus.com/reference/clibrary/csignal/signal