Сон в потоке вызывает утечку памяти - PullRequest
6 голосов
/ 27 июня 2011

Я заглянул в код моего предка и обнаружил утечку в следующей ситуации:

1) Запустить приложение
b) После запуска приложения закройте приложение в течение 4 секунд

Сообщение об утечке:

f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\thrdcore.cpp(306) : {58509} client block at 0x016DFA30, subtype c0, 68 bytes long.

Впоследствии, я просмотрел код, обнаружил подозрительную точку причины на 4 секунды сна при управлении функцией рабочего потока.

Тестовая программа:

UINT InitThread(LPVOID pParam)
{
      Sleep(4000);  //4000 is the default value, it reads from a registry key.
      CMyMFCTestProjectDlg* pTest = (CMyMFCTestProjectDlg*)pParam;
      pTest->DoSomething();  
      return 0;  //--> Exit thread
}

BOOL CMyMFCTestProjectDlg::OnInitDialog() {
...
AfxBeginThread(InitThread, this);
...
}

Если я уменьшу / уберу таймер сна, утечка будет устранена.
Однако я хотел бы знать, как это происходит.Либо из-за прерывания рабочего потока или потока GUI?Будет ли рабочий поток выходить после того, как поток GUI вызовет эту проблему?

Кто-нибудь может поднять мне настроение, помогая мне объяснить это?Я потерян ....

Ответы [ 3 ]

6 голосов
/ 27 июня 2011

Похоже, что рабочий поток не имеет возможности правильно закрыться после закрытия приложения, поскольку процесс завершается до его завершения.Операционная система, как правило, довольно хорошо справляется с очисткой ресурсов, поэтому это может не быть проблемой.Однако, вероятно, лучше подождать, пока этот поток не выйдет, прежде чем позволить приложению завершить работу.Хотя это звучит так, что это приведет к 4-секундной задержке завершения работы вашего приложения.

Если это неприемлемо, вам придется добавить некоторый механизм в поток, чтобы получать событие завершения работы из основного потока приложений,Например, если вы замените рабочие потоки "sleep" на WaitForSingleObject события:

DWORD res = WaitForSingleObject(
    shutdownEvent,
    4000); // timeout
if(res == WAIT_OBJECT_0)
{
    // received the shutdownEvent, exit
    return 0;
}
// The delay has elapsed, continue with rest of thread.
. . .

Затем, когда вы завершаете работу в главном потоке, установите событие, затем дождитесь потокачтобы выйти, он должен выйти почти сразу:

SetEvent(this->shutdownEvent);
WaitForSingleObject(pThread->m_hThread, INFINITE); // pThread is returned from AfxBeginThread
4 голосов
/ 27 июня 2011

Вы должны корректно завершить свои потоки, прежде чем ваш процесс исчезнет. Вы можете либо попросить главный поток дождаться выхода другого (-их) потока (-ов), либо дать основному потоку сигнал о выходе из другого (-их) потока (-ов).

0 голосов
/ 27 июня 2011

68 байт?

Если приложение действительно закрывается, т.е. исчез из диспетчера задач «Приложения» и «Процессы», и . Единственный эффект этой «утечки» - выдача сообщения отладки при раннем закрытии, просто отключите отладку и забудьте об этом.

Вероятно, это аббревиатура завершения работы MFC, некая структура, которая не может быть безопасно освобождена во время завершения работы и оставлена ​​для очистки ОС.

С 99,9% приложений, которые не перезапускаются / останавливаются непрерывно, утечка в 68 байт при завершении работы, даже если она не была очищена, не окажет заметного влияния на работу машины Windows между интервалами перезагрузки. применяется каждый «вторник исправлений».

Я уверен, что у вас есть еще много ошибок с более серьезными эффектами, с которыми нужно иметь дело. Если нет, вы можете иметь немного моего!

Rgds, Martin

...