Click to open or copy the MUTEXES project files.
MUTEXES is an MFC sample that demonstrates the use of the CMutex synchronization object. MUTEXES is a dialog-based application that creates two CWinThread objects and uses them to perform a simple task under the user's control.
When the sample starts, it presents a list box that is being filled by one of two threads the program creates.
You can adjust the priority of the counter thread and the display thread independently using the combo boxes near the top of the dialog box. You can also adjust the process priority, which affects the behavior of both threads in the process relative to other processes in the system, by using the Process Priority dialog box.
When the application starts, the display thread begins converting an integer stored in the application to a string and then adds the string to a list box. The other thread in the application, meanwhile, is busy incrementing that integer by one in a tight loop.
If you check the Synchronize check box, the threads will use a CMutex and CSingleLock object to make sure both threads don't try to reference the string or the integer at the same time. When Synchronize isn't checked, you'll notice that the content of the list box is not very orderly. When Synchronize is checked, you'll find that the application smoothly increments the counter and that the strings added to the box are in numerical order.
By default, the Pause checkbox isn't checked. If you check it, the execution of both threads will be suspended. By pausing the threads, you can examine the output in the list box while the threads aren't busy adding more strings.
The counter thread generates no output unless you check the Show Counter Thread checkbox.
MUTEXES is based on the MUTEXES sample from Jeffery Richter's book, Advanced Windows 32 from Microsoft Press, and is used with his permission. This MFC version of MUTEXES is written in C++ using MFC, while Richter's sample uses C and standard Windows API calls. Aside from the conversion, the programs function in the same way.
You can learn more about the details of the application's functionality by reviewing the MUTEXES source code or by reading Richter's commentary in his book.
The only major difference in the two samples is in the way they shut down the threads. Richter's example uses ::TerminateThread, and the MFC version of MUTEXES shuts down the threads when the application terminates.
The CWinThread object doesn't have a TerminateThread member function. The ::TerminateThread API is quite dangerous — it terminates a thread's execution without hesitation. A thread that is manipulating an internal data structure might leave that data structure in an indeterminate state as it terminates early.
As a result, the logic for the WM_CLOSE handler in the dialog box of the MFC sample is a bit more complicated than the similar handler in Advanced Windows 32 because it carefully orchestrates the termination of the threads.
This sample demonstrates the following keywords:
AfxBeginThread; AfxGetApp; CButton::GetState; CButton::SetCheck; CComboBox::AddString; CComboBox::GetCurSel; CComboBox::SetCurSel; CDC::DrawIcon; CDC::GetSafeHdc; CDialog::DoModal; CListBox::AddString; CListBox::DeleteString; CListBox::GetCount; CListBox::SetCurSel; CMenu::AppendMenu; CMultiLock; CMutex; CRect::Height; CRect::Width; CSemaphore; CString::Empty; CString::IsEmpty; CString::LoadString; CSyncObject; CWinApp::Enable3dControls; CWinApp::InitInstance; CWinApp::LoadStdProfileSettings; CWnd::DoDataExchange; CWnd::GetClientRect; CWnd::GetDlgItem; CWnd::IsIconic; CWnd::OnClose; CWnd::OnPaint; CWnd::OnQueryDragIcon; CWnd::OnSysCommand; CWnd::PostMessage; CWnd::SendMessage; GetCurrentProcess; GetDlgItem; GetExitCodeThread; GetSystemMenu; GetSystemMetrics; IsDlgButtonChecked; LoadIcon; PostMessage; ResumeThread; SetOwner; SetPriorityClass; SetThreadPriority; Sleep; SuspendThread