Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multithreading and MFC

I am writing a multithreaded app. On the main thread is the main window which is a modeless dialog box. When the user clicks on the start button, it will create a new thread that does some stuff for a long time. On the main thread it will create a new modeless dialog box to display the status of that new thread, 1 per thread. I created kind of a template dialog box using the resource editor and I set a static text for the status to have an id of IDC_STATIC_NUMCYCLE. I poll the status of the threads during the OnIdle function. The updating of the status works with 1 thread only, but if I spawn more the static text for all will not update until the very end or if it is the only thread left running.

Declaration:

map<CSimDlg *, CSimulator *> simulations;

My OnIdle function:

BOOL CFGSim1App::OnIdle(LONG lCount)
{
CWinApp::OnIdle(lCount);

DWORD exitCode;
CString numOfCycle;

for (map<CSimDlg *, CSimulator *>::iterator iter = simulations.begin(); iter != simulations.end();)
{
    // skip already finished threads
    if (iter->second == NULL)
    {
        iter++;
        continue;
    }
    if (GetExitCodeThread(iter->second->m_hThread, &exitCode))
    {
        if (exitCode == 0)
        {
            delete iter->second;
            iter->second = NULL;

            if (IsWindow(iter->first->m_hWnd))
            {
                iter->first->SetDlgItemText(IDC_STATIC_SIMSTATUS, L"Simulation done");
            }
            else
            {
                iter = simulations.erase(iter);
            }
        }
        else
        {
            ULONG64 temp = iter->second->m_ul64NumOfCycle;

            if (temp % 10000 == 0)
            {
                numOfCycle.Format(_T("%d"), temp);
                iter->first->SetDlgItemText(IDC_STATIC_NUMCYCLE, numOfCycle);
            }

            iter++;
        }
    }
    else
    {
        iter++;
    }   
}

return TRUE;
}

I am guessing the problem is with the id of the static text. Is there a way to work around this? Or do I need to declare a different id for each dialog box? Or is the problem elsewhere?

like image 343
Felix Palomares Avatar asked Aug 05 '26 04:08

Felix Palomares


1 Answers

The (temp % 10000 == 0) condition is suspicious to me. You are assuming that temp will increment slowly enough that 10000 marks will be detected. This may not be the case. If you want to reduce GUI operations then introduce a "last count" variable for each thread, and update GUI only if temp is sufficiently larger than this variable, that is then set to temp.

BTW you don't need std::map if all you do with the container is to traverse trough it, and don't use special features of the map. It might as well be a list of std::pair, or list of some new structure. This new structure could hold the mentioned last count variable.

like image 200
Dialecticus Avatar answered Aug 07 '26 21:08

Dialecticus