Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> завершение потока в dllmain 
:(
    Опции темы
Lazin
Дата 16.10.2007, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 8
Всего: 154



Ситуация такая:
dll-ка создает объект, объект, в свою очередь, запускает поток. Для завершения потока используется event, который устанавливается в деструкторе объекта. Но, как выяснилось, когда деструктор начинает выполняться - поток уже не работает.

Код

class CActiveObj
{
HANDLE event;
  public:
  CActiveObj()
  {
    //здесь создается поток
  }

  ~CActiveObj
  {
    ::SetEvent(event);
    //ждем завершения потока
  }

   ********

  unsigned int ThreadExec(void*)
  {
    while(true)
    {
        HANDLE events[] = {event, ....};
        DWORD r = ::WaitForMultipleObjects(EVENTS_COUNT, events,  FALSE, INFINITE);
        if (r == WAIT_OBJECT_0) {::_endthread();}
        else *****
    }
  }
};

dllmain.cpp
Код

CActiveObj * obj = NULL;

BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved)
{
    switch ( dwReason )
    {
        case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls( hinstDLL );
            obj = new CActiveObj();
        break;

        case DLL_PROCESS_DETACH: 
            delete obj;
        break;
    }
    return TRUE;
}

По идее при выполнении DLL_PROCESS_DETACH объект должен быть удален и поток остановлен, но этого не происходит, так как поток в момент выполнения delete obj; уже мертв.
Как правильно дождаться завершения потока в dllMain, и возможно-ли это.


Это сообщение отредактировал(а) Lazin - 16.10.2007, 14:55
PM MAIL Skype GTalk   Вверх
Nastya
Дата 16.10.2007, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 27.3.2002
Где: Мариуполь

Репутация: 3
Всего: 44



Запоминай HANDLE потока и жди его WaitForSingleObject 


--------------------
Что бы понять рекурсию, надо понять рекурсию

"Профессионал - это человек сделавший все возможные ошибки в очень узкой области". Н.Бор
PM MAIL   Вверх
Lazin
Дата 16.10.2007, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 8
Всего: 154



Цитата(Nastya @  16.10.2007,  15:06 Найти цитируемый пост)
Запоминай HANDLE потока и жди его WaitForSingleObject  

Я так и делаю,
Код

  ~CActiveObj
  {
    ::SetEvent(event);
    //ждем завершения потока
  }

на самом деле вместо комментария там ф-я WaitForSingleObject, которой в качестве аргумента передается хэндл потока. Дело в том что когда управление доходит до этого места поток уже завершен. 
Кстати забыл написать, что без dll код работает нормально (если подключить мой исходник к проекту). Но проблема в том что нужно именно в качестве длл. Мне кажется это связано с тем, что код который выполняется в потоке физически находится в dll, поэтому система и убивает его при выгрузке длл-ки, но точно я не знаю. 


PM MAIL Skype GTalk   Вверх
SergeCpp
Дата 16.10.2007, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


 
**


Профиль
Группа: Участник
Сообщений: 955
Регистрация: 8.8.2005
Где: At Home

Репутация: 10
Всего: 124



Всего кода не вижу, но Вам стоило бы вот так примерно подстраховаться против выгрузки DLL

Код
            // load once more to prevent from unloading when hook removed
            // also set handle

            g_hClockDLL = LoadLibrary( g_pClockDLLName );

            DWORD tid; // Win9x requirement for CreateThread()

            CloseHandle( CreateThread( NULL,
                                       0x2000,    // initial commit stack size
                                       ( PTHREAD_START_ROUTINE )ClockMain,
                                       NULL,    // some parameter can be passed if needed
                                       0,
                                       &tid ) );
//... файл Clock.cpp


(там нечто аналогичное Вашему с потоками делается)

PM MAIL WWW ICQ   Вверх
Lazin
Дата 17.10.2007, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 8
Всего: 154



Цитата(SergeCpp @  16.10.2007,  23:45 Найти цитируемый пост)
(там нечто аналогичное Вашему с потоками делается)

спасибо за исходник, но там немного не то происходит, что мне нужно.
Ситуация такая:
Есть множество программ, использующих мою библиотеку(статичесски). Когда одна из программ загружает dll, мой код создает поток. При выгрузке библиотеки, нужно дождаться завершения потока, который должен выполнить определенную работу. Так вот, когда в ф-и DllMain выполняется
Код


case DLL_PROCESS_DETACH: 
            delete obj;
break;

поток завершается, но не нормальным образом - как при TerminateThread.
Возможности изменить клиентский код у меня нет.
PM MAIL Skype GTalk   Вверх
SergeCpp
Дата 17.10.2007, 11:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


 
**


Профиль
Группа: Участник
Сообщений: 955
Регистрация: 8.8.2005
Где: At Home

Репутация: 10
Всего: 124



Проверьте точку входа DLL (если явно не ставили в опциях, то MSVC вызовет сначала свою)

Я бы не использовал всякие надстройки типа ::_endthread();

И перечитайте внимательнее Рихтера и MSDN по данному вопросу

В качестве проверок поставьте точки прерывания в ключевых местах

Удачи Вам! Тут несложно, только делать нужно самому, согласны?

PM MAIL WWW ICQ   Вверх
Lazin
Дата 17.10.2007, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 8
Всего: 154



SergeCpp, Ok
PM MAIL Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

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


 




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


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

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