Visual C++ 6 Unleashed

Visual C++ 6 Unleashed

By MICKEY WILLIAMS and David Bennett

Using Multiple Threads in Your Application

If you have created an MFC application with AppWizard, your application already is set up to handle multiple threads. If not, you have to be certain to link with the multithreaded libraries, which you can set up in the C/C++ | Code Generation page of the Project Settings dialog box. This is generally a good thing to do anyway, because there are few situations in which your application will require the single-threaded libraries; you also need to use the multithreaded varieties if you plan to use MFC.

MFC Objects and Threads

As discussed earlier, when an application has multiple threads running at the same priority level, the order in which they are executed is somewhat random. Because of this, you must take special care to ensure that two different threads are not attempting to modify certain objects at the same time. You will see how to do this later, in the section, "Thread Synchronization"; for now, keep in mind that individual MFC objects may not be used by multiple threads simultaneously. If two threads access the same CString object at exactly the same time, for example, the results are unpredictable at best.

If you will be using MFC objects in your threads, you must create the thread by using the CWinThread class, as you will see here. Threads that are created without using a CWinThread object will not properly initialize the internal variables that MFC needs to work with multiple threads. For example, if you create a thread directly with the C runtime library _beginthreadex() function, the resulting thread will not be able to use MFC objects or other MFC functions.

In addition, although threads share the same memory space, they do not share the same structures that MFC uses to map C++ objects to Windows handles. In general, this means that a thread may access only handle-based MFC objects (such as instances of classes derived from CWnd) created in that thread. There are, however, ways around this that you will look at later, in the section, "Using User-Interface Threads."

Types of Threads

MFC implements two types of threads. Although both types use the same underlying Win32 API thread mechanisms and both use CWinThread, they are different in the way that MFC adds functionality to the thread.

If you are interested in creating a thread that simply goes off on its own and does something, such as background calculations, without interfacing with the user, you use what MFC calls a worker thread. These threads are based on CWinThread, but you do not need to explicitly create a CWinThread object, because a call to the AfxBeginThread() function creates one for you.

If, on the other hand, you want to create a thread that deals with parts of a user interface, you create a user-interface thread. MFC adds a message pump to these threads, providing a message loop that is separate from the main message loop of your application's CWinApp object. Actually, CWinApp is itself a prime example of a user-interface thread, because it is derived from CWinThread. Just as MFC derives CWinApp from CWinThread, you create your own class derived from CWinThread to implement user-interface threads.

Share ThisShare This

Informit Network