Summary application performance is not just about speed. In a WEB server environment, superior performance also means ensuring that the maximum number of users can be serviced concurrently. This can be achieved by efficiently using multiprocessor computers and threading management. This article describes the techniques that can be used to solve many of the concurrency problems. One approach is to use thread management, which controls access to the database on a thread basis-which protects the integrity of the data. In this article, you build and provide a reusable thread class. These classes are then tested and their performance is analyzed in the actual environment.
The success of the server application will sooner or later be attributed to performance. However, performance in a server application is not exactly equivalent to sheer speed. You must also consider concurrency-that is, how many clients you can serve at the same time. In fact, concurrency is often more important for servers than pure speed, especially for high-end hardware with many CPUs. server applications with low concurrency simply cannot take advantage of multiple CPUs, regardless of how fast the application is.
I don't know if there's a simple prescription for optimizing concurrency, but over the years I've developed a lot of tips that can provide great help. One trick is to synchronize access to objects in a large collection without sacrificing concurrency. This article will demonstrate my skills. First, I'll explain a small multithreaded sample program that demonstrates the need to access objects in a large collection concurrently. Then I'll develop a reusable class that solves the problem and compare the resulting performance values. As an added benefit, the sample program will contain a set of easy to use classes for creating and synchronizing threads (of course, reusable).
The sample code can be run on Windows 2000 with Service Pack 6a, Windows NT, or with Service Pack 1 (it may run on other versions, but the above version of the Second Edition It's all the versions I've tested. Also, this code requires Visual C + + 6.0 with Service Pack 4.
Note that I use a slightly different coding style than the Windows programming world specification. Specifically, I use the identifier prefix k_ to represent constants and enumerations, use G_ to represent global variables, static global variables, and static class members, and use M_ to represent class members.
Building Blocks
Figure 1 Exception Class
class Exception
{
public:
enum ErrId
{
// Keep these in the same order as the string table:
k_critSecInitFailure,
k_threadCreationFailure,
k_threadResumeFailure,
k_threadWaitFailure
};
Exception(ErrId errId, unsigned long osErrId = NOERROR) :
m_errId(errId), m_osErrId(osErrId) {}
~Exception()
{}
UINT getErrId() const
{ return m_errId; }
unsigned long getOsErrId() const
{ return m_osErrId; }
string getErrorMsg() const;
private:
static string getOSMsg(unsigned long osErrId);
static const char*const k_messages[];
UINT m_errId;
unsigned long m_osErrId;
};