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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Завершение потока, созданного _beginthreadex 
:(
    Опции темы
soldatx
Дата 2.2.2009, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 18.8.2008

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



Нужда помощь, каким образом принудительно завершить поток созданный _beginthreadex!
Предположим есть  класс
 
Код

class Aclass
{
private:
 HANDLE hw;
 Aclass()
{ 

hw = (HANDLE) _beginthread (myFunc,0,NULL);

}
void Stop(void)
{
TerminateThread(hw,0);
CloseHandle(hw);
}
}

При вызове метода Stop поток завершается, однако переменные,которые используются  в myFunc не освобождаются что приводит к утечке памяти. Да и ваабще на сколько я понял TerminateThread не рекомендуется использовать. Собственно вопрос в том как корректно завершить поток созданный таким образом!
PM MAIL   Вверх
Fazil6
Дата 2.2.2009, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: нет
Всего: 60



Цитата(soldatx @  2.2.2009,  12:22 Найти цитируемый пост)
Собственно вопрос в том как корректно завершить поток созданный таким образом! 

например выставить некий флаг. Внутри главного цикла потока, проверять его. Если TRUE, то поток сам должен завершиться
PM MAIL   Вверх
Earnest
Дата 2.2.2009, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 33
Всего: 183



Поток создается всегда функцией CreateThread, что бы там ни было накручено до нее.

Корректно поток может завершиться только сам. Для чего необходимо предусмотреть соответствующие механизмы в функции потока. И лучше использовать события, а не флаги. 

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



--------------------
...
PM   Вверх
lv151
Дата 2.2.2009, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: 1
Всего: 2



Почитай Рихтера, у него очень подробно всё описано.
http://www.ozon.ru/context/detail/id/4079733/

Это сообщение отредактировал(а) lv151 - 2.2.2009, 21:20
PM MAIL   Вверх
soldatx
Дата 3.2.2009, 06:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 18.8.2008

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



Спасибо  за советы! Про события c использованием setEvent  и WaitForSingleObject читал, вродебы понял как и что но вот в чем загвоздка, есть следующий код, который выполняется в потоке:
Код

ArgsThread* Args = (ArgsThread*) args;
    HANDLE hDir = CreateFile(Args->Path.c_str(), // pointer to the file name
      FILE_GENERIC_READ,                // access (read/write) mode
    FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,  // share mode
    NULL,                               // security descriptor
    OPEN_EXISTING,                      // how to create
    FILE_FLAG_BACKUP_SEMANTICS,         // file attributes
    NULL                                // file with attributes to copy
  );

  DWORD nBufSize = 16384;
  
  BYTE *pBuf = new BYTE[nBufSize];
 
  DWORD BytesReturned;
  FILE_NOTIFY_INFORMATION *pInfo;
  while( ReadDirectoryChangesW(
                                hDir,                                  // handle to directory
                                pBuf,                                    // read results buffer
                                nBufSize,                                // length of buffer
                                TRUE,                                 // monitoring option
                                FILE_NOTIFY_CHANGE_LAST_WRITE|
                                FILE_NOTIFY_CHANGE_SIZE|
                                FILE_NOTIFY_CHANGE_DIR_NAME|
                                FILE_NOTIFY_CHANGE_FILE_NAME,             // filter conditions
                                &BytesReturned,              // bytes returned
                                NULL,                          // overlapped buffer
                                NULL// completion routine
                                ))
    {

        
        
  string helper_txt;

  pInfo = (FILE_NOTIFY_INFORMATION*)pBuf;
  for (;;)
  {
    switch(pInfo->Action)
    {
    case FILE_ACTION_ADDED: helper_txt = "The file was added to the directory"; break; 
      case FILE_ACTION_REMOVED: helper_txt = "The file was removed from the directory"; break; 
      case FILE_ACTION_MODIFIED: helper_txt = "The file was modified. This can be a change in the time stamp or attributes.";break; 
      case FILE_ACTION_RENAMED_OLD_NAME: helper_txt = "The file was renamed and this is the old name.";break; 
      case FILE_ACTION_RENAMED_NEW_NAME: helper_txt = "The file was renamed and this is the new name."; break;
      default : helper_txt = "Чета случилось"; break;
    }

    if (pInfo->NextEntryOffset==0) break;
    pInfo = (FILE_NOTIFY_INFORMATION *)(((BYTE *) pInfo) + pInfo->NextEntryOffset); 
    
  }
   
}
  CloseHandle(hDir);
  delete pInfo; 
  delete pBuf;

1 .так вот дело в том что, немогу понять в каком месте мне вставить проверку флага или WaitForSingleObject ... в нутрь цыкла ReadDirectoryChangesW тогда выход из цикла произойдет не сразу а когда ReadDirectoryChangesW сгенерит событие изменения файловой системы.
2. как правильно создать флаг(событие) в классе что бы  к ниму можно было обратиться из потока, у меня компилятор ругается ...  недопустимая ссылка на нестатический член 'ClassA::_flag'

PM MAIL   Вверх
soldatx
Дата 3.2.2009, 07:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 18.8.2008

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



Единственное что приходит пока в голову это использовать переменные pInfo и pBuf как глобальные для класса и очищать их в месте с TerminateThread ....

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


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



в цикл While подставляй
Код

bool flExit = false; 
  while(! flExit)
 {
   
         ReadDirectoryChangesW(
                                hDir,                                  // handle to directory
                                pBuf,                                    // read results buffer
                                nBufSize,                                // length of buffer
                                TRUE,                                 // monitoring option
                                FILE_NOTIFY_CHANGE_LAST_WRITE|
                                FILE_NOTIFY_CHANGE_SIZE|
                                FILE_NOTIFY_CHANGE_DIR_NAME|
                                FILE_NOTIFY_CHANGE_FILE_NAME,             // filter conditions
                                &BytesReturned,              // bytes returned
                                NULL,                          // overlapped buffer
                                NULL// completion routine
                                )

         WaitResult = WaitForSingleObject(hEventEnableReceive, 10);
      if(WaitResult == WAIT_OBJECT_0)
      { 
       // Тут если надо выйти из потока
           flExit = true;
       }
      if(WaitResult == WAIT_TIMEOUT)
      { 
       continue;
       }    
  } 
  {



--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
soldatx
Дата 3.2.2009, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 18.8.2008

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



Да все бы ничего только в этот участок кода 
Код

         ReadDirectoryChangesW(
                                hDir,                                  // handle to directory
                                pBuf,                                    // read results buffer
                                nBufSize,                                // length of buffer
                                TRUE,                                 // monitoring option
                                FILE_NOTIFY_CHANGE_LAST_WRITE|
                                FILE_NOTIFY_CHANGE_SIZE|
                                FILE_NOTIFY_CHANGE_DIR_NAME|
                                FILE_NOTIFY_CHANGE_FILE_NAME,             // filter conditions
                                &BytesReturned,              // bytes returned
                                NULL,                          // overlapped buffer
                                NULL// completion routine
                                )

         WaitResult = WaitForSingleObject(hEventEnableReceive, 10);
      if(WaitResult == WAIT_OBJECT_0)
      { 
       // Тут если надо выйти из потока
           flExit = true;
       }
      if(WaitResult == WAIT_TIMEOUT)
      { 
       continue;
       }    

я попадаю не сразу когда вызываю SetEvent, а когда происходит событие в файловой системе, только после этого отрабатывает :
Код

 WaitResult = WaitForSingleObject(hEventEnableReceive, 10);
      if(WaitResult == WAIT_OBJECT_0)
      { 
       // Тут если надо выйти из потока
           flExit = true;
       }
      if(WaitResult == WAIT_TIMEOUT)
      { 
       continue;
       }    


PM MAIL   Вверх
Dem_max
Дата 3.2.2009, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



У тебя функция  ReadDirectoryChanges блокирующая ? если нет непонятно в чем проблемы.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
soldatx
Дата 3.2.2009, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 18.8.2008

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



по всей видемости да ... она забирает себе управление до тех пор пока в каталоге, который она просматривает не произойдет событие , после чего отдает управление дальше ((
PM MAIL   Вверх
Dem_max
Дата 3.2.2009, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



а конкретней ? 


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
xvr
Дата 3.2.2009, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Переведи ReadDirectoryChangesW в overlapped режим и жди в WaitForMultipleObjects 2 event'а - один от ReadDirectoryChangesW и второй твой терминирующий

PM MAIL   Вверх
soldatx
Дата 4.2.2009, 05:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 18.8.2008

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



Цитата
overlapped режим
 
как раз про это думал буду пробовать, спасибо за наводку. Dem_max конкретней уже не могу похоже запутался оканчательно, ну ниче разберусь пади.

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


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 18.8.2008

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



Что ж всем спасибо видемо вопросс решен однако предоставлю код который получился, я новичек в общем и поэтому буду очень признателен если глянете этот код и дадите пару подзатылников если заслужил 
Код

{

    
    ArgsThread* Args = (ArgsThread*) args;
    
    HANDLE hDir = CreateFile(Args->Path.c_str(), // pointer to the file name
    FILE_LIST_DIRECTORY  ,                // access (read/write) mode
    FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,  // share mode
    NULL,                               // security descriptor
    OPEN_EXISTING,                      // how to create
    FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,         // file attributes
    NULL                               // file with attributes to copy
  );

    if (hDir == NULL)
        _endthread();

OVERLAPPED ov;

ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);;

HANDLE hEvents[2];
hEvents[0] = ov.hEvent;
hEvents[1] = Args->EventStop;
enum EventsFileWatch Event;
DWORD nBufSize = 1024;
BYTE pBuf[1024];
DWORD BytesReturned;


FILE_NOTIFY_INFORMATION *pInfo;
while( true)
{

    ReadDirectoryChangesW(
                                hDir,                                  // handle to directory
                                pBuf,                                    // read results buffer
                                nBufSize,                                // length of buffer
                                TRUE,                                 // monitoring option
                                FILE_NOTIFY_CHANGE_LAST_WRITE|
                                FILE_NOTIFY_CHANGE_SIZE|
                                FILE_NOTIFY_CHANGE_DIR_NAME|
                                FILE_NOTIFY_CHANGE_FILE_NAME,             // filter conditions
                                &BytesReturned,              // bytes returned
                                &ov,                          // overlapped buffer
                                NULL// completion routine
                                );
DWORD dwRes = WaitForMultipleObjects(2,hEvents,false, INFINITE);

if (dwRes == WAIT_OBJECT_0+1)
{
    _endthread();
}

if (dwRes == WAIT_OBJECT_0)
{
     ResetEvent(hEvents[0]);
    
    DWORD dwSize = 0;
    BOOL bRes = GetOverlappedResult(hDir, &ov, &dwSize, FALSE);
    if (bRes == FALSE)
        _endthread();

    
  pInfo = (FILE_NOTIFY_INFORMATION*) pBuf;
  for (;;)
  {
    switch(pInfo->Action)
    {
      case FILE_ACTION_ADDED: Event = WM_FILE_ADDED; break; 
      case FILE_ACTION_REMOVED: Event = WM_FILE_REMOVED; break; 
      case FILE_ACTION_MODIFIED: Event = WM_FILE_MODIFIED;break; 
      case FILE_ACTION_RENAMED_OLD_NAME: Event = WM_FILE_OLD;break; 
      case FILE_ACTION_RENAMED_NEW_NAME: Event = WM_FILE_NEW; break;
      default :  break;
    }

       char lpFileName[MAX_PATH];
       WideCharToMultiByte(CP_ACP, 0, pInfo->FileName, pInfo->FileNameLength/2, lpFileName, MAX_PATH, 0, 0);
       lpFileName[pInfo->FileNameLength/2] = 0;
       string FullPath = Args->Path +"\\" + lpFileName;       
       SendMessage(Args->hwndMainWindow, WM_FILENOTIFY_CHANGED, (WPARAM) Event, (LPARAM) FullPath.c_str());
    if ( pInfo->NextEntryOffset==0) break;
    pInfo = (FILE_NOTIFY_INFORMATION *)(((BYTE *) pInfo) + pInfo->NextEntryOffset); 
    
  }
}  
}
  CloseHandle(hDir);
  delete  pInfo; 
 }



Добавлено через 3 минуты и 23 секунды
А и еще ламерский вопросс (извеняюсь что не в тему) ... как можно проверить есть ли утечка памяти или нет! Я просто в диспетчере задач смотрел скоко занимает до создания и после удаления объекта и чуствую что это не правильно!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.0576 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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