|
[Errata][Reviews][Additional
Comments][Exercises and Questions][Performance][Win32vsCLib][Critical Comments][WindowsCE][NT vs UNIX][Additional
Sample Programs][Additional Resources][About
the Author]
This material has been assembled for the convenience of readers.
It will be updated from time to time.
Last modified: July 16, 1999
Please send comments and suggestions directly to me: jmhart@world.std.com
Errata that apply to Printing 1
Errata that apply to Printing 2
See copyright page in front of book for printing number information.
If you are considering purchasing this book, it might help to read several on-line
reviews and a collection of reader comments.
Observations and clarifications based primarily on reader questions.
These questions will test your understanding of the sample programs and point out
interesting details in the program logic. Common techniques for using the Win32 API are
noted. There are also suggestions as to how to enhance or improve the programs. I have
used many of these questions in courses based on the book.
Appendix C shows sequential file procession performance using the ASCII-to-Unicode
programs. This section shows the results using files much larger than the 5MB input file
used for the Appendix C results. In some cases, the memory-mapped results are not as
favorable as in Appendix C. This section also shows results where memory is flushed to the
file at the end and where there is no buffering in the file access version.
This information augments the discussion on Pages 65-66 regarding the choice between
Win32 and the Standard C Library (SCL) and the more comprehensive C Run-Time Library
(CRTL) when performing file I/O.
This section contains a variety of comments criticizing, in a constructive manner,
various aspects of the Win32 design (disclaimer: as a whole, I like the API) and
implementation. These comments are my own or, in some cases, have come from readers and
course participants. Additional reader comments are welcome, as is any information that
augments or corrects my statements.
This section contains my thoughts on this favorite topic. I've also included comments
from readers, colleagues, and others.
This section analyzes performance when several threads contend for a single resource.
Graphs, with analysis, show performance results under a variety of circumstances, and a
test program is included for carrying out additional experiments. Readers have contributed
significantly to the test results and interpretation. Critical sections will normally
provide superior performance (under NT), but, surprisingly, this is not always the case.
Contending for critical sections when running more than four threads or when running in
the background can be slower than using mutexes, and performance can degrade dramatically.
Furthermore, under Windows 95/98, CS performance is better in the background than in the
foreground.
Finally, critical sections provide no performance benefit at all when running on an SMP
system and two threads are running on different processors and contending for the same
critical section. CRITICAL_SECTION.SMP performance is
significantly degraded when using multiple processors in such situations, and you will get
better performance by forcing all contending threads on a specific processor using the
thread processor affinity mask.
The program in this section can be also used as a simple method of estimating
performance of threaded, synchronized code using different synchronization techniques. It
also allows you to test the effect of serializing thread execution and using nested
CS/Mutex calls, and parameters allow you to simulate the effect of CPU-intensive and
I/O-intensive threads. The number of threads concurrently contending for the same resource
is another command-line argument.
This section includes a test program, performance results with graphs, and
analysis.
This example constructs a semaphore with an atomic multiple-unit wait, generalizing the
very limited implementation on Page 235. There are also a number of comments about testing
and debugging threaded applications, related synchronization problems, and the relative
features of semaphores, mutexes, and events.
The example:
- Illustrates many interesting and non-trivial aspects of Win32 synchronization. In
particular, we can compare event, mutex, and semaphore behavior and see the utility of
each.
- Demonstrates shared memory between processes. The book did not contain a good example of
this.
- Constructs new synchronization objects that are useful and can be used to solve some
hard synchronization problems. The objects are sharable and securable, just like the other
synchronization objects.
- The test program illustrates a prototype multiple producer/consumer model.
There are three source files. The function library is first, then the header file, and,
finally, the test program.
A reimplementation of pipe (Program 9-1) using named
pipes in byte mode.
This program, contributed by a reader, is similar to the other copy programs in Chapter
2, and it is comparable to the memory-mapped ASCII to Unicode program, atouMM, in Chapter 6. It further demonstrates the speed of
memory-mapped I/O and illustrates some alternate coding styles to those I used in the
book.
This is a reimplementation of Program 8-9 (the periodic alarm) using the "waitable
timers" that are available with Visual C++ 5.0. There are no message loops, and you
will gain flexibility with this technique.
You may want to look at Chapter 13's discussion on "alertable wait functions"
(page 277) as alertable waits are used by the program.
Constructed from a mutex and an event.
This is of general interest for anyone interested in threads and synchronization. The
example illustrates many interesting aspects of Win32 synchronization, and it is a
special case of the multiple wait semaphore (previous example). There are three source
files, as follows:
- SemphWCE.c
The implementation of the Create,
Wait, Release, and Close functions.
- Synchize.h
The header file.
- TestSych.c
The test program - a multiple producer/consumer
system.
This is a reimplementation of Program 7-3, which initializes a security descriptor
using the Visual C++ 5.0 functions BuildExplicitAccessWithName
and BuildSecurityDescriptor. They make the task a lot
easier, but there is a catch. I have not been able to get them to work as described. Let
me know if you have a solution, and I'll update this program.
comp.os.ms-windows.programmer.win32 is an excellent
place to go for additional information or to get answers to your questions. I have found a
lot of valuable information, and there is a core group of five or so individuals who
quickly respond with good answers to some very difficult questions. Also, the tone of
civility is commendable (unlike some groups I've seen); sarcastic and personal comments
are rare, and even the most basic questions and silly mistakes seem to be tolerated and
gently corrected.
Steve Loughran's FAQ About Win32
Programming page is a helpful resource.
Listing the Running Processes
The Chapter 8 job management programs allow you to manage processes that are created
under job management. In many cases, however, you may want to find out all the processes
running on the system; that is, you would like the equivalent of the UNIX ps
command. There is no obvious way to list all the running processes, but take a look at http://www.codeguru.com/win32/ps.shtml
for a solution to the problem. Note: I have not tested this; use at your own risk.
|