The principal function of the parent-child process work in Nginx

Source: Internet
Author: User

Based on Nginx (0.7.67 version) code, the basic process creation, process body and event processing of Nginx are briefly analyzed.
Basically, the parent process (that is, the main process) initially initializes and reads the configuration, loads the functions of each module, and then Fork () out n sub-processes (that is, worker processes), with the same working logic and functionality. The parent process is responsible for monitoring the signal (such as hup,quit, etc.), passing the signal to the child process via the socket pair (the child process generally does not communicate). The child process passes events to handle signals passed by the parent process. Because each child process shares a service listening port (such as HTTP 80), the event invocation function of the child process is triggered when the user sends the request. Therefore, at the time of the Accept () request, a mutex is required to ensure that only one worker process accepts and processes the request.
The entrance to the Nginx main process is the same as the General program's main () function, and its code is this: int ngx_cdecl main (int argc, char *const *argv) {/*...*/
//Nginx attempts to read the ID of the listener interface from the environment variable at the time of the previous execution.// and creates a corresponding number of ngx_listening_t structure variables (stored in the cycle->listening array), /// then call this interface through GETSOCKNAME,GETSOCKOPT and other system calls to the original set of interface property information and // Set parameters read out to set those newly created ngx_listening_t structure variables, thus inheriting the previous execution // time of the listener interface, this interface is called before ngx_init_cycle
if (ngx_add_inherited_sockets (&init_cycle)! = NGX_OK) {return 1;}
/*...*/
The//ngx_modules array is defined in objs/ngx_modules.c ngx_max_module = 0;for (i = 0; ngx_modules[i]; i++) {ngx_modules[i]-& Gt;index = ngx_max_module++; Each module is numbered}
//ngx_init_cycle () function, this is a more important function, is the main, ngx_master_process_cycle// and ngx_single_process_cycle calls, where the latter two are called at the time of reconfigure. // Its main work is that the initialization cycle is based on the old cycle; will inherit many of the properties of the old cycle, // such as log, but also reallocate many resources, such as pool, shared mem, file handler, //listening sockets, while clearing old cycle resources //Read the configuration file is also done herecycle = ngx_init_cycle (&init_cycle);
if (ngx_process = = Ngx_process_single) {ngx_single_process_cycle (cycle);} else { / / General Process requests with multiple processesngx_master_process_cycle (cycle); }}
//main body of the master process (that is, the parent process)//This function will start the work process, and will handle the semaphore, process will kill or create a new processvoid Ngx_master_process_cycle (ngx_cycle_t *cycle) { //Add the signal to the listener set set Sigemptyset (&set),//sigemptyset () is used to initialize the parameter set signal set and empty Sigaddset (&set, SIGCHLD) //sigaddset () Adds a signal to the signal set 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));
/*...*/
//According to worker_processes number in ngx_core_conf_t, start several work process ngx_start_worker_processes (cycle, Ccf->worker_ processes, ngx_process_respawn);
///The following loop handles different states differently, while those states are mostly different signals received by the process//ngx_signal_t signals[] array defines the signal and the processing method: Ngx_signal_handler ()//signal in NGX_ Init_signals () inside Initialize//in Ngx_signal_handler (), according to Ngx_process to decide whether it is master process or//worker process (that is, both master and worker call Ngx_signal_handler // to process the signal)
for (;;) { //hangs the current process, waits for a signal, exits from the suspended state, resumes execution of the//set recording the current monitored signal sigsuspend (&set);/* various signal processing, such as ngx_shutdown_signal,ngx_reconfigure_signal, etc. * / /* Omit */ }}

the//ngx_start_worker_processes () function, which is specified by the number of N, ngx_worker_process_cycle ()//number for the parameter call Ngx_spawn_process () to create the work process and initialize the related resources and attributes;Execution function Ngx_worker_process_cycle of the child process; broadcasts the currently created//worker process information; Each process opens a channel (Ngx_pass_open_channel ())//n is the number of worker process//type is the way to create new processes, such as Ngx_process_respawn, Ngx_process_just_respawnstatic void Ngx_start_worker_processes (ngx_cycle_t *cycle, ngx_int_t N, ngx_int_t type){ ngx_int_t i; ngx_channel_t ch;
Ch.command = Ngx_cmd_open_channel;
for (i = 0; i < n; i++) { //Read CPU allocation from config cpu_affinity = ngx_get_cpu_affinity (i); //ngx_spawn_process set Ngx_process_slot to be assigned to the child process.//Idle Slots ngx_spawn_process (cycle, ngx_worker_process_cycle, NULL, "worker process", type); Ch.pid = ngx_processes[ngx_process_slot].pid; Ch.slot = Ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; //ngx_pass_open_channel put this worker's channel[0] and process ID //Offset slot broadcast in the process table (Ngx_write_channel ()) to all other already //created worker. //In this way, after all the processes have been created, each worker gets all the other worker's //channel[0].Ngx_pass_open_channel (cycle, &ch);     }}

ngx_pid_t ngx_spawn_process (ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data, Char *name, ngx_int_t respawn) /c12>{/*...*///If the type is ngx_process_detached, the description is Hot code substitution (Hot code substitution is also//functions are processed), so you do not need to create a new socketpair. if (respawn! = ngx_process_detached) {//establish Socketpair//create socketpair for interprocess communication, the master process creates a pair for each worker //socket, master process space opens all Socketpair channel[0], //channel[1] handles at both ends. When a worker is created, the worker inherits the master that is currently created and //Open all Socketpair. This worker is initialized (call Ngx_worker_process_init) to close // This process corresponds to Socketpair's channel[0] and other worker ///channel[1], keep open this process corresponds to Socketpair channel[1] and other // worker corresponding to channel[0], and listen to the process corresponding to Socketpair // /channel[1] for readable events. in this way, each worker has the other worker's //channel[0], can sendmsg (Channel[0], ...) Send a message to another worker /*...*/}
/*...*///Create child process pid = fork ();switch (PID) {case-1:ngx_log_error (Ngx_log_alert, Cycle->log, ngx_erRNo, "fork () failed while spawning"%s "", name);Ngx_close_channel (Ngx_processes[s].channel, Cycle->log); return ngx_invalid_pid; //In the subprocess, perform the function of passing in the child process, case 0:ngx_pid = Ngx_getpid (); // call Ngx_worker_process_cycle ()///NOTE: This function defines the loop in which the child processes handle events. That is, the child process does not //Execute the statement after the function proc (cycle, data); break;default:break;}
}
the body of the//worker processstatic void Ngx_worker_process_cycle (ngx_cycle_t *cycle, void *data) {//Set some environment variables//Call the init_process hook function for all modules //Channel[1 of other processes] closed, its own exception//child process inherits the parent process's ngx_processes array, but the child process only listens to its own channel[1]//Put your own channel[0] off//Because your own channel[0] is given to other child processes that are used to send messages sendmsg//Call the Ngx_add_channel_event () function to register a read event handler for Ngx_channel. Ngx_worker_process_init (cycle, 1);//main loop, handling eventsfor (;;) {/*... */
// call Epoll, monitor events periodically //Receive connections first (do not handle events), and process signal between processes (if any) //handling events inside the Accept Queue and event queue Ngx_process_events_and_timers (cycle);
/*... */}
/*... */}

The principal function of the parent-child process work in Nginx

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.