Visual Studio Threads

From Minor Miracle Software
Revision as of 14:10, 24 June 2019 by WikiSysop (talk | contribs) (Thread Safety)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Visual Studio Threads
Microsoft MFC C++ Threads.

Thread Synchronization[1]

Maybe not shit
Thread Example 1[2]
Threads vs Processes

Create a Worker Thread with:
AfxBeginThread(<function name>
Create a User Interface Thread with:
CWinThread *pThread = AfxBeginThread( RUNTIME_CLASS ( <class name> ) );


Sources

  1. Visual C++ .NET Developers Guide (2002) McGraw-Hill
  2. Multithreading with C++ and MFC[3]
  3. bogotobogo.com example.[4]

McGraw-Hill p. 88-99 Threads. Critical Section. - Done.

MFC Threads

All threads in MFC applications are represented by CWinThread[5] objects.

Call the framework helper function AfxBeginThread[6], which creates the CWinThread object for you.

Threads come in two types: User-interface threads and worker threads. User-interface threads are commonly used to handle user input and respond to events and messages generated by the user. Worker threads are commonly used to complete tasks, such as recalculation, that do not require user input.

MFC handles user-interface threads specially by supplying a message pump for events in the user interface. CWinApp is an example of a user-interface thread object, because it derives from CWinThread and handles events and messages generated by the user. The Win32 API does not distinguish between types of threads; it just needs to know the thread's starting address so it can begin to execute the thread. MFC handles user-interface threads specially by supplying a message pump for events in the user interface. CWinApp is an example of a user-interface thread object, because it derives from CWinThread and handles events and messages generated by the user.

Race conditions apply to threads with the usual dangers.

Special attention should be given to situations where more than one thread might require access to the same object. Multithreading: Programming Tips[7] describes techniques that you can use to get around problems that might arise in these situations. Multithreading: How to Use the Synchronization Classes[8] describes how to use the classes that are available to synchronize access from multiple threads to a single object.

Processes and Threads[9]

A job object allows groups of processes to be managed as a unit. Nameable, securable, shareable, and control the processes associated with them. End the job object and all associated objects end as well.

A thread pool is a collection of worker threads that efficiently execute asynchronous callbacks on behalf of the application. The thread pool is primarily used to reduce the number of application threads and provide management of the worker threads.

A fiber is a unit of execution that must be manually scheduled by the application. Fibers run in the context of the threads that schedule them.

Processes vs. Threads

Critical Sections

A critical section is code that application threads can access only one thread at one time. If two threads require access to the same critical section at the same time, the first to make the request will obtain access. The second thread must wait until the first thread completes its task. Critical sections are always bottlenecks in application. If you find a race condition, that part is a critical section.

There are two ways to create a critical section for use with threads: a CRITICAL_SECTION variable or a CCriticalSection object. The CCriticalSection object is the easiest and least error prone to use. All you need to do is create a CCriticalSection object, then use the Lock() and Unlock() methods as needed to either restrict or allow access to a section of code. Here’s an example of what a typical critical section sequence might look like.

Example 1. Critical Section Object

    CCriticalSection oMySection; // Critical section object.

   // Lock the critical section.
   if (!oMySection.Lock())
       AfxMessageBox("Failed to lock critical section", MB_OK);
   // Do some critical work here.
   // Unlock the critical section.
   if (!oMySection.Unlock())
       AfxMessageBox("Failed to unload critical section.", MB_OK);

CCriticalSection methods return a BOOL that signifies success or failure. So each Lock and Unlock section needs a handler for success or failure. Sometimes Lock is used inside a loop until a successful lock is achieved. The Lock method does take a parameter value, but that is ignored.

Thread Safety

Some libraries are thread safe, other are not. When in doubt, assume the library, class, object, e.t.c. is NOT thread safe. The danger being, as always, a race condition.

To make a library thread safe use critical sections and isolate the variables in each thread. No thread should have to search outside for a variable.

Any MFC object is thread-safe at the class level but not at the object level. For example, two threads could access different objects derived from the same class, but not the same object. A single CString object that two different threads need to access must grant access in sequence. With the first thread finishing its work before the second thread starts using it. Only UI and Worker threads can use MFC objects safely.

Examples

  1. bogotobogo Example 1
  2. MS CreateThreads Example 1

Internal Links

Parent Article: Visual Studio Notes