Шаг 338 - Объекты MFC и синхронизация

Сам язык C++, C не имеет средств для поддержки многопоточной работы. Поэтому ответственность за многопоточную работу лежит на MFC раз мы ей пользуемся. Но MFC не использует взаимоисключений. Вот так. Вся ответственность за синхронизацию и доступ к объектам MFC лежит на нас. MFC проверяет доступ только для глобальных объектов и структур, но и то только в версии Debug. Но и это еще не все. В MFC нельзя пользоваться для создания потоков WIN 32 API. Вот так. Это связано с тем, что MFC при создании потоков проводит инициализацию всяких ей нужных переменных. Ну давайте посмотрим пример. Надо немного изменить предыдущий шаг.

UINT Threads(LPVOID pParam)
{
	CWinApp* cw= AfxGetApp();
	cw->HideApplication(); 
	return 0;
}

void CTestThreadDlg::OnStart() 
{
	// TODO: Add your control notification handler code here
	AfxBeginThread(Threads,NULL);
}

Мы из другого потока хотим получить доступ к объекту приложения, который создан в основном потоке приложения. Запустив приложение и нажав на кнопку в отладочной версии мы получим сообщение об ошибке.

338.gif (3788 b)

При отладке мы увидим, что ошибка произошла вот здесь:

ASSERT((CWnd*)p == this);  

А внизу примерно такое объяснение.

// Примечание: если любое из вышеупомянутого утверждений вызвано, и Вы
// пишите multithreaded приложение, это вероятно 
// Вы передали C ++ объект от одной нити к другой
// и использовали тот объект в процессе, который не был предназначен для этого.
// (только простые встроенные функции  должны использоваться)
//
......

Вроде как что-то работает. Но обратите внимание на макрос ASSERT он работает только в отладочной версии и все. Переключитесь на конфигурацию Release используя меню Set Active Configuration и этот код сработает как миленький, как будто ничего и не бывало. Приложение спрячется. Найти его можно через Ctrl-Alt-Delete.

Вывод. MFC Вам не помощник и реализуйте синхронизацию сами !!!


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем.