Multithreading using MFC – Microsoft Foundation Classes

·

Multithreading in MFC (Microsoft Foundation Class) can be accomplished using either worker threads or UI threads. Here’s an overview of both approaches and how to implement them in MFC.

1. Worker Threads

Worker threads are background threads that don’t interact directly with the user interface (UI). They are useful for performing long-running operations in the background without freezing the main UI.

Example: Creating a Worker Thread

You can create a worker thread using the AfxBeginThread function.

UINT MyThreadFunction(LPVOID pParam)
{
    // Perform your task in the background
    for (int i = 0; i < 10; ++i)
    {
        // Simulate some work
        Sleep(1000); // Sleep for 1 second
    }
    return 0; // Thread completed
}

void StartWorkerThread()
{
    CWinThread* pThread = AfxBeginThread(MyThreadFunction, NULL);
    if (pThread == nullptr)
    {
        AfxMessageBox(_T("Thread creation failed!"));
    }
}
  • MyThreadFunction: The function that will run on the worker thread.
  • AfxBeginThread: Used to create a new worker thread.

Communication Between UI and Worker Thread

If you want the worker thread to communicate with the UI (e.g., to update progress), you should use thread-safe mechanisms like posting messages to the main thread.

UINT MyThreadFunction(LPVOID pParam)
{
    CWnd* pWnd = (CWnd*)pParam;
    for (int i = 0; i < 10; ++i)
    {
        // Simulate work
        Sleep(1000);

        // Post a message to the main thread to update progress
        pWnd->PostMessage(WM_USER_UPDATE_PROGRESS, i);
    }
    return 0;
}

// In your dialog class
afx_msg LRESULT OnUpdateProgress(WPARAM wParam, LPARAM lParam)
{
    int progress = (int)wParam;
    // Update UI with progress
    return 0;
}

BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
    ON_MESSAGE(WM_USER_UPDATE_PROGRESS, &CMyDialog::OnUpdateProgress)
END_MESSAGE_MAP()
  • PostMessage: Sends a message from the worker thread to the UI thread.
  • ON_MESSAGE: Declares a handler for custom messages in MFC.

2. UI Threads

UI threads in MFC are threads that have their own message loops. These threads are used when you need to create or manipulate UI elements (such as windows or dialogs) in the new thread.

Example: Creating a UI Thread

class CMyUIThread : public CWinThread
{
    DECLARE_DYNCREATE(CMyUIThread)

public:
    virtual BOOL InitInstance();
    virtual int ExitInstance();
};

IMPLEMENT_DYNCREATE(CMyUIThread, CWinThread)

BOOL CMyUIThread::InitInstance()
{
    // Create a dialog or window here
    CDialog myDialog(IDD_MY_DIALOG);
    myDialog.DoModal(); // Modal dialog
    return TRUE;
}

int CMyUIThread::ExitInstance()
{
    // Cleanup code here
    return CWinThread::ExitInstance();
}

void StartUIThread()
{
    CWinThread* pThread = AfxBeginThread(RUNTIME_CLASS(CMyUIThread));
    if (pThread == nullptr)
    {
        AfxMessageBox(_T("UI Thread creation failed!"));
    }
}
  • CWinThread: Base class for both worker and UI threads in MFC.
  • InitInstance: Where you initialize any UI components in the thread.
  • ExitInstance: Handles thread cleanup.

Thread Synchronization

When multiple threads access shared resources, you should use synchronization primitives such as CRITICAL_SECTION, CMutex, or CEvent to avoid race conditions.

Example: Using Critical Sections

CRITICAL_SECTION cs;

void SomeSharedFunction()
{
    EnterCriticalSection(&cs);
    // Access shared resource
    LeaveCriticalSection(&cs);
}

void InitializeCriticalSectionExample()
{
    InitializeCriticalSection(&cs);

    // Make sure to delete the critical section once you're done
    DeleteCriticalSection(&cs);
}

This ensures that only one thread can access the critical section at a time, avoiding race conditions.

Summary

  • Worker Threads: Perform background work; use AfxBeginThread to create them.
  • UI Threads: Handle UI components in a separate thread; use CWinThread and AfxBeginThread for creation.
  • Synchronization: Use thread-safe methods like critical sections, mutexes, or events for resource sharing.

Let me know if you need any further details or specific examples!

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *