Apache2 process/thread model

Source: Internet
Author: User

Apache2 has two types of processes: Master process (master_main) and child process (child_main ).

Three threads are derived from sub-processes:

1. Control thread controls the thread. Is the main thread. Creates an accept thread and worker threads to receive and execute control commands of the master process.
* Events.

2. The Listener threads processes the listener.
3. worker threads processes Data Interaction

 

// C: \ httpd-2.2.17-win32 \ Server \ MPM \ winnt \ mpm_winnt.c
Master_main ()

Apache2 uses apr_proc_create to create a new process. In Windows, the createprocessasuserw function is called.

Mpm_winnt.c is a dedicated mpm (Multi-Channel Processing Module) optimized for Windows NT. It uses a separate parent process to generate a separate sub-process, in this sub-process, multiple threads are generated in turn to process requests. That is to say, mpm_winnt can only start two processes: Parent and Child. It cannot start multiple processes at the same time as in Linux. Mpm_winnt optimizes Apache through the threadsperchild and maxrequestsperchild parameters. The following describes in detail. The threadsperchild parameter is used to set the number of threads for each process. After these threads are created at startup, the child process will no longer create new threads. on the one hand, because mpm_winnt cannot start multiple processes, this value must be large enough to handle possible request peaks. On the other hand, this parameter is subject to the server response speed, if the number is too large, it slows down. Therefore, a reasonable value must be balanced comprehensively.
The default value on mpm_winnt is 64, and the maximum value is 1920. We recommend that you set the value between and. If the server performance is high, the value is larger. Otherwise, the value is smaller.

 

/*************************************** ********************************
* Master_main ()
* Master_main () runs in the parent process. It creates the child
* Process which handles HTTP requests then waits on one of three
* Events:
*
* Restart_event
*-------------
* The restart event causes master_main to start a new child process and
* Tells the old child process to exit (by setting the child_exit_event ).
* The restart event is set as a result of one of the following:
* 1. An Apache-K restart command on the command line
* 2. A command received ed from Windows Service Manager which gets
* Translated into an ap_signal_parent (signal_parent_restart)
* Call by code in service. C.
* 3. The child process calling ap_signal_parent (signal_parent_restart)
* As a result of hitting maxrequestsperchild.
*
* Shutdown_event
*--------------
* The shutdown event causes master_main to tell the child process
* Exit and that the server is shutting down. The shutdown event is
* Set as a result of one of the following:
* 1. An Apache-K shutdown command on the command line
* 2. A command received ed from Windows Service Manager which gets
* Translated into an ap_signal_parent (signal_parent_shutdown)
* Call by code in service. C.
*
* Child Process Handle
*--------------------
* The child process handle will be signaled if the child process
* Exits for any reason. In a normal running server, the signaling
* Of this event means that the child process has exited prematurely
* Due to a Seg fault or other irrecoverable error. For Server
* Robustness, master_main will restart the child process under this
* Condtion.
*
* Master_main uses the child_exit_event to signal the child process
* To exit.
**************************************** ******************************/

Thread startup

If (parent_pid! = My_pid) | one_process ){
// The child process or in one_process (Debug) Mode
...
Child_main (pconf );...
}
Else {
// A Real-Honest to goodness parent
...
Restart = master_main (ap_server_conf, shutdown_event, restart_event );
...
}

 

In the preceding example, one_process is used to determine the command line parameter one_process started by the program. This command line parameter is saved in the global variable ap_server_config_defines at startup. To run httpd in single-process mode (without the console), you can use-done_process on the command line. The other is to directly write the variable to ap_server_config_defines In the hook after startup.

// Insert the following code into the ap_hook_post_config () HOOK,
Char ** new_start_arg;
New_start_arg = (char **) apr_array_push (ap_server_config_defines );
* New_start_arg = "one_process ";

 

Note the lifecycle of the * new_start_arg string. In this example, it points to a static string, which is valid during the process lifecycle. If it points to a stack variable, it may become a wild pointer.

 

Void child_main (apr_pool_t * pconf)
{
...
For (I = 0; I <ap_threads_per_child; I ++ ){
...
Child_handles [I] = (handle) _ beginthreadex (null, (unsigned) ap_thread_stacksize,
Worker_main, (void *) I, 0, & tid );
...
} Create_listener_thread ();
...
}

 

 

Static void create_listener_thread ()
{
...
/* Now start a thread per listener */
For (LR = ap_listeners; LR = LR-> next ){
If (LR-> SD! = NULL ){
_ Beginthreadex (null, 1000, winnt_accept, (void *) LR, 0, & tid );
}
}
}

 

 

Thread termination:

 

Practice:

Create only one listener:

Scenario Design:

When we configure httpd as a multi-port listener, we want to identify the port from which the received data comes from. Httpd creates a thread for each port.

Ap_listeners ()

 

Main Code of the sub-process:

 

Complete child_main Process

// Child. c
Handle exit_event;
Static int shutdown_in_progress = 0;
Static int workers_may_exit = 0;

Static pcomp_context winnt_get_connection (pcomp_context context)
{
While (1 ){
If (workers_may_exit ){
Return NULL;
}
}
}
Static unsigned int _ stdcall winnt_accept (void * LR _)
{
While (! Shutdown_in_progress ){
Sleep (100 );

}
If (! Shutdown_in_progress ){
/* Yow, hit an irrecoverable error! Tell the child to die .*/
Setevent (exit_event );
}
Ap_log_error (aplog_mark, aplog_info, apr_success, ap_server_conf,
"Child % d: accept thread exiting.", my_pid );
Return 0;
}

Void child_main (apr_pool_t * pconf)
{
Handle child_events [2];
Child_events [0] = exit_event;
While (1 ){
/* Check to see if the child has been told to exit */
If (waitforsingleobject (exit_event, 0 )! = Wait_timeout ){
Break;
}
/* Wait for previous generation to clean up an entry in the scoreboard */
Apr_sleep (1 * apr_usec_per_sec );
}
While (1 ){
Rv = waitformultipleobjects (2, (handle *) child_events, false, 1000 );
CLD = RV-wait_object_0;
If (RV! = Wait_timeout & RV! = Wait_failed & CLD = 0 ){
Ap_log_error (aplog_mark, aplog_notice, apr_success, ap_server_conf,
"Child % d: Exit event signaled. Child process is ending.", my_pid );
Break;
}
}
Shutdown_in_progress = 1;
/* Tell the worker threads to exit */
Workers_may_exit = 1;
}

 

 

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.