Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Насчет потоков сделанных с пом. CWinThread, (кто знает MFC) 
:(
    Опции темы
mr.DUDA
Дата 21.8.2003, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



Плз, народ объясните мне, в чем фишка:
1) создаю класс производный от CWinThread
2) запускаю поток AfxBeginThread(RUNTIME_CLASS(CMyThread)), получ. указатель на объект "поток"
3) поток завершает работу (выход из функции Run())
4) ну и что теперь с указателем (кто вызывал деструктор ? как теперь память занятую объектом освободить, не вызывая "delete" деструктор повторно ? confused.gif )

Может, надо переделать без CWinThread (решил, блин, попробовать на свою голову smile.gif ) ?


--------------------
user posted image
PM MAIL WWW   Вверх
Step
Дата 22.8.2003, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: 5
Всего: 25



как ты проток завершаешь


--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
mr.DUDA
Дата 22.8.2003, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



Поток я создавал и завершал так:
Код
class CRunThread: public CWinThread
{
public:        
     int  *ptr;
     HANDLE  m_evtStop;
     HANDLE  m_evtStopped;

     CRunThread()
     {
           ptr = new int;
           m_evtStop = CreateEvent(NULL, FALSE, TRUE, NULL);
           m_evtStopped = CreateEvent(NULL, FALSE, TRUE, NULL);
     }
     ~CRunThread() {delete ptr;}

     // ... (всякие макросы, типа DECLARE_DYNCREATE и AFX_VIRTUAL)

     virtual  int  Run()
     {
           while(1)
           {
                       if(WaitForSingleObject(m_evtStop)==WAIT_OBJECT_0)
                                   break;
           }
           SetEvent(m_evtStopped);
           return CWinThread::Run();   // можно "return 1" -- ничего не изменится
     }

     // ...
};

class CModuleGlobal
{
public:
     CRunThread *m_pThread;

     CModuleGlobal()
     {
           m_pThread = (CRunThread *)AfxBeginThread(RUNTIME_CLASS(CRunThread));
     }

     ~CModuleGlobal()
     {
           SetEvent(m_pThread->m_evtStop);
           WaitForSingleObject(m_pThread->m_evStopped, INFINITE);
           delete m_pThread;  // будет ошибка повторного освбождения памяти
     }
};

Если из деструктора CModuleGlobal убрать "delete m_pThread", будет утечка памяти из-за того, что память под "m_pThread->ptr" не освобождена. Если же оставить "delete m_pThread", то появляется ошибка из-за повторного удаления памяти, выделенной под "m_pThread", т.е. память под объект "CRunThread" удаляется где-то в недрах MFC сразу же по окончании функции "Run", а вот деструктор "CRunThread::~CRunThread" почему-то MFC не вызывается.

Вообще-то, из-за гемора с CWinThread я уже переделал всё под обычный WinAPI поток, осталось очень неприятное впечатление об MFC sad.gif.


--------------------
user posted image
PM MAIL WWW   Вверх
Step
Дата 22.8.2003, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: 5
Всего: 25



Цитата
"CRunThread" удаляется где-то в недрах MFC сразу же по окончании функции "Run", а вот деструктор "CRunThread::~CRunThread" почему-то MFC не вызывается.
Цитата
Если из деструктора CModuleGlobal убрать "delete m_pThread", будет утечка памяти из-за того, что память под "m_pThread->ptr" не освобождена.
противоречешь


--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
mr.DUDA
Дата 22.8.2003, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



(я хотел сказать, MFC удаляет память под объект "m_pThread", но не вызывает деструктора CRunThread::~CRunThread, поэтому память под "m_pThread->ptr" не освобождается)

Как я выяснил, просидев в отладке полчасика, MFC всё-же вызывает деструктор объекта "CRunThread", но не всегда. Бывают случаи, когда при выходе из приложения поток завершается раньше, чем MFC успевает до конца выполнить _AfxThreadEntry, а может всё дело в другом -- короче, имхо проще и безопаснее использовать обычные функции для создания потока из WinAPI.


--------------------
user posted image
PM MAIL WWW   Вверх
Step
Дата 22.8.2003, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: 5
Всего: 25



а ты не пробывал вызывать afxendthread


--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
mr.DUDA
Дата 22.8.2003, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



afxendthread вызывается автоматически после выхода из Run():
Thrcore.cpp
Код
UINT APIENTRY _AfxThreadEntry(void* pParam)
{
// ...

// first -- check for simple worker thread
DWORD nResult = 0;
if (pThread->m_pfnThreadProc != NULL)
{
 nResult = (*pThread->m_pfnThreadProc)(pThread->m_pThreadParams);  // вызов Run
 ASSERT_VALID(pThread);
}

// ......

// cleanup and shutdown the thread
threadWnd.Detach();
AfxEndThread(nResult);      // <--------------------- вот оно

return 0;   // not reached
}


Это сообщение отредактировал(а) mr.DUDA - 22.8.2003, 16:12


--------------------
user posted image
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0486 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.