httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "jlwpc1" <>
Subject Re: Windows 2.0 MPM design issues
Date Fri, 02 Jun 2000 16:19:44 GMT

From: Bill Stoddard <>

Great a good flow in "writing" but my "just" questions below - you may be 100% right but I
don't yet understand this "odd" Windows flow. :) 

Also I would like to see something like this outline flow from OtherBill for the install problems.

> Very good MPM overview. Continue with Win32 specific MPM details...
> The WIN32 MPM creates two processes. The parent process and the parent process creates
a child
> process. The child process is multithreaded and is responsible for processing all HTTP

In Windows most other started processes are for doing something that the main process doesn't
really care to "know" about.


Say a  tech writer's word editor wishes to display a calculator for the tech writer. The editor
doesn't really care if it is used or not but allows via Windows to copy text and to close
the calculator with or without the editor knowing.  In other words the calculator doesn't
need any of the process info from the editor in order to work. The calculator only needs to
be installed on the computer where this editor can find it. (Correction - now adays it needs
to be _anywhere_ in the world where the editor can find it).

Two separate processes used together.  

Yes you can have other processes "talk to each other" (Java.exe talking to the server) but
this is not the first "way" to design a Windows program that only uses itself.  Is there an
old one process with threads that failed for Windows in the CVS?

What is wrong with Apache's process A starting threads to do everything needed in your process
B?  I ask this question at the end again if you only want to answer once. :)

> The parent process:
> 1. Creates the AcceptEx IO Completion Port (IOCP for short) (I won't attempt explain
this. I'd take
> too many words)

Yes for now - skip. 

A computer is just bits turned off and on and people make them do things that other people
never thought of.  With this in mind, remember that IOCP _was_ designed to be used in _one_
process. That is _how_ IOCP takes care of all those threads via the device and uses multi-processors.
This (so they say) makes it easier for the programmers.

Easy to say, but really sometimes hard to do.  (another MS way)   <g>

> 2. Opens all the listen sockets
> 3. Creates the child process

Here again why a process?  (you sure this is not just old Unix way thinking?)

> 4. Passes a duplicated IOCP handle to the child (parent communicates to the child via
pipe, NOT
> shared memory)

Not needed if not a separate process.  

But for now why not shared memory? 

> 5. Passed duplicated listen socket handles to the child (via a pipe)

Not needed if not a separate process.

Threads have access to everything in the process.

> 6. Waits for a restart or shutdown event (from an external process) or a child exit (normal
> abnormal)

Same for a process with threads only?  

> 7. When one of the above events is signaled, the parent does the right thing (restarts
the failed
> child process, signals the child process to die gracefully and optionally on restart,
restarts a new
> child process to take the place of the old child process.)

This has to be Windows "heavy". Starting and stopping this other process just to do the work
that one process's threads should/would do?

Same for a process with threads only?

> 8. Thats it! The parent process job is very simple.

Just the opposite of real life. :)

> Steps 1, 2, 4 & 5 could be done directly in the child process. Doing them in the
parent process
> allows the sockets (and pending connections in the listen queue) to be maintained across
a server
> restart. Doing these steps in the child process would cause all pending connections to
be dropped
> across a restart.

All in the one process is better yes?  But why the child process?

> The main thread in the child process:
> 1. Receives the IOCP and duplicated sockets
> 2. Does initialization required to begin accepting connections
> 3. Creates a pool of worker threads which accept requests off the listen sockets (the
details differ
> a bitr depending on whether you are on NT or not). When a connection is received, a thread
> the connection and processes the request that comes in on that connection.
> 4. Starts accepting requests
>     95/98 requests are accepted on a separate thread. NT uses an IOCP.

Does all this sound like the same for a process using threads only?

> 5. The main child thread then waits for a shutdown event (or on NT, a server maintenance
> If the main thread received a server maintenance event, it does some IOCP magic to increase
> number of connections that can be handled). When it receives a shutdown event (either
generated by a
> worker thread or generated by the parent process), it shutdowns the worker threads gracefully
> eventually exits.

Same for a process with only threads?

> There is a start_mutex which prevents more than one child process from accepting requests
at once.

So to me this one child is just acting like a thread in Windows terms.  Why not a Process
A thread in the first place?

> The WIN32 MPM uses threads as the "execution primitive". Apache 1.3 on Windows used threads
as well.
> The NT specific code uses IO Completion ports and does accepts asynchronously. Worker
threads are
> dispatched off the IOCP in LIFO order, which is pretty cool. This is the first step to
getting to a
> fully asynchronous server (which is my goal). What does this mean? Today the server is
not fully
> asynchronous, which means that you require 1 thread per concurrently connected client.
> concurrent clients implies the need for 2000 threads. Now threads are lighter weight
than processes,
> but that still cost resources. A fully async server could handle those 2000 concurrent
clients with
> 1 thread (or realistically, a few threads) because that thread would NEVER block on network

Yes, all handled by the IOCP magic with Apache helper functions - like there is a how  much
of the CPU used function?  There is a threads usage function?   Globals used?

Process A
   Creates setup threads for OtherBills troubles (more someday).  - these die sometime
(on a side note - before you add a service first have an "app" for the service to run)
   if OtherBill's stuff works go on if not quit
(Here is where the service takes over the app's main thread)
(Or if not a service then never mind)
           Creates the IOCP stuff  (sets thread count to processor count)
           Creates thread pool, trackers.
           Starts the IOCP loop  (checks for quit/restart/also)
           Starts listening.
           Surf away 
(Here the service dies and the app gets back it's main thread)
   Clean up, go home and cut the lawn.

Process B
 A Service Control Program with user interface to remotely control the Apache service.

Process C
 Log goodies, etc.

Process D

NT/Win2000 could follow Process A above but Win9x (luckily can only have 100 sockets) needs
a different thread pool idea. Still using a lot of the functions designs of NT/Win2000, like
- thread usage tracker, CPU usage, set up, etc.  But then again these functions are written
differently - same idea but different DLLs used and different function names. I really do
suggest TWO if not four exe files. 

As a side note the DLLs used (and structures) for Win2000 are different than the NT ones for
writing these system tracker functions. (four exe files?)  Anyway I'm getting off the subject
- more below.

> Hope this helps.
> Bill

Yes it is a good written example, but I must be missing something - why the other process?
 Killing and starting that other process has to be bad and heavy on ole Windows and the server.
 Why are threads in process A not a better way than this (maybe created over and over) process


View raw message