Re[4]: handle
От: Polosaty Беларусь  
Дата: 05.04.02 05:46
Оценка: 3 (1)
Здравствуйте Dancer, Вы писали:

D>Здравствуйте Polosaty, Вы писали:


P>>Здравствуйте adontz, Вы писали:


A>>>Здравствуйте Dancer, Вы писали:


A>>>На выходе убивай поток TerminateThread, так, на всякий случай.

P>>Настоятельно не рекомендуется так делать, поток должен завершаться корректно. А с остальным согласен. Проблема в том, что не завершается поток и, следовательно, процесс. И не забывайте делать CloseHandle, правила хорошего тона все-таки стОит соблюдать.

D>А что, разве когда объект CWinThread уничтожается, его handle не освобождается автоматически?

Так сложилось, что я не использую MFC для программирования потоков. Поэтому мне приходится делать CloseHandle ручками. Если его делает MFC — на здоровье.
Кстати, закрытие хэндла с помощью CloseHandle и освобождение хэндла — не одно и то же с точки зрения ОС. Главное, что делает CloseHandle — декремент счетчика привязок объекта. Это не означает, что хэндл будет освобожден тут же. Хэндл освобождается, когда счетчик привязок станет равным нулю (т.е. когда все потоки, пользующие, например, семафор, сделают CloseHandle, или когда все потоки, получившие каким-то образом хэндл другого потока, т.е. икрементировавшие счетчик привязок объекта, сделают CloseHandle и сам поток завершится и т.д.)

D>И вообще, по-русски handle — это что (переводится вроде как "описатель")? И чем функционально отличается от указателя на объект? Многие ф-ции типа GetExitCodeThread принимают в качестве параметра, идентифицирующего объект, его handle, а не указатель. Почему?

Хэндл функционально действительно подобен указателю, но имеет дополнительные свойства. Главные из дополнительных свойств таковы:
1) указатель актуален в пределах адресного пространства одного процесса, ну а хэндл можно пользовать (если грамотно) в разных процессах, в т.ч. наследовать. Правда, при этом в разных процессах значение одного и того же хэндла может быть разным;
2) хэндл может быть актуален даже тогда, когда описываемый им объект (как ты правильно заметил, хэндл по-русски — описатель) перестал существовать (например, когда поток завершился, хэндл может быть еще не освобожден и с его помощью можно получит код возврата потока).

Хэндл — это описатель объекта ядра ОС. Каждый объект ядра имеет структуру, его описывающую, которая, в частности, включает и счетчик привязок. Используя для доступа к объекту ядра хэндл и функции API, программер не должен думать и не может забыть об инкременте или декременте счетчика привязок, об удалении объекта ядра, если его счетчик привязок стал равен 0 и т.д.

Ну а на самом деле хэндл — это индекс в таблице процесса, которая содержит указатели на эти самые структуры, описывающие объекты ядра. Структура этой таблицы — закрытая информация, но ее можно представлять себе так. В таблице присутствуют 4 столбца:
1. индекс (т.е. значение хэндла);
2. указатель на блок памяти ядра (т.е. ту самую структуру, описывающую объект ядра);
3. маска доступа;
4. набор битовых флагов.

Вообще, лучше всего на эту тему почитать Рихтера. Собственно, практически вся привденная мной информация взята оттуда.
Re[9]: Чья вина?
От: SergH Россия  
Дата: 03.04.02 14:05
Оценка: 2 (1)
Здравствуйте Dancer, Вы писали:


D>void CFractalDlg::OnCancel()

D>{
D> // TODO: Add extra cleanup here
D> if(m_flag==1)
D> {
D> g_eventKill.SetEvent();//Это прерывает выполнение цикла в рабочем потоке
D> ::WaitForSingleObject(g_eventFinished, INFINITE);//А это так, типа рабочий поток из цикла вышел
D> //и сейчас завершится
D> }
D>
D> CDialog::OnCancel();
D> //PostQuitMessage(0);//Со страху сюда поставил сначала, потом в OnDestroy() поробовал — все равно не работает
D>}

PostQuitMessage(0) в данном случае не причём. 99% — ты висишь в ожидании установки g_eventFinished. Просто убери строчку с WaitForSingleObject(...) и программа будет завершаться. Если "просто убирать" не хочется, проверь, что рабочий поток действительно завершается при установке g_eventKill и что перед смертью он действительно устанавливает g_eventFinished. Если бы это был API, вместо g_eventFinished можно было бы ждать освобождения описателя потока, он освобождается при завершении потока. MFC я знаю хуже, но думаю тоже можно.
Делай что должно, и будь что будет
Re: Чья вина?
От: iLYA Канада http://www.bizon.org/ilya/
Дата: 03.04.02 06:14
Оценка: 1 (1)
Здравствуйте Dancer, Вы писали:

D>Ситуация такая: при попытке повторно отлинковать проект, VC выдае ошибку "нет доступа к файлу .exe". Попробовал удалить вручную — "файл используется Windows" и действительно нет доступа. Причем доступ появляется после перезагрузки, но исчезает после первой же линковки или через несколько раз. Я со страху переставил VC, а потом и винды, да толку никакого. Но этот эффект появился, когда я стал запускать отдельный поток для вычислений, хотя он у меня должен завершаться до завершения программы. Может в этом быть виновата моя программа или это глюк среды VC или виндов?


Прю...
Неправильно закрываешь приложение. И у тебя остается процесс. Если работаешь под Win2000 запусти TaskManager, иначе из VS Tools ProcessView и увидешь, что твоя программа не закрылась
Попробуй у себя прописать так:


        case WM_DESTROY:
            PostQuitMessage(0);
            break;


Удачи,
iLYA
Re[3]: Чья вина?
От: Курилка Россия http://kirya.narod.ru/
Дата: 03.04.02 07:42
Оценка: 1 (1)
Здравствуйте Dancer, Вы писали:

<skip>
D> А где прописать?

В оконной процедуре (WndProc)

D>The PostQuitMessage function indicates to the system that a thread has made a request to terminate (quit). It is typically used in response to a WM_DESTROY message.


D>C другой стороны

D>The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future.

D>Когда система посылает главному потоку WM_DESTROY он сам себе посылает WM_QUIT что ли?


WM_DESTROY посылается окну, а не потоку! Типа говорит, что окошко убито, всё — надо закругляться, соответственно, приложение делает последние завершающие действия и говорит: ок, закругляемся ( PostQuitMessage), и очередь сообщений убивается!

В моём представлении это примерно так выглядит
Re[11]: Чья вина?
От: Курилка Россия http://kirya.narod.ru/
Дата: 03.04.02 14:09
Оценка: 1 (1)
Здравствуйте Dancer, Вы писали:
D>А MFC почему не любишь? Интересно мнение человека, который может сравнивать, исходя из собственного опыта.

Какой там опыт — мне ещё программить и программить до настоящего программиста, зелёные мы...
Поэтому своих мыслей про MFC приводить не буду, глянь вот лучше сюда
Автор(ы): Александр Шаргин
Дата: 21.04.2001

Первая часть статьи посвящена основам WTL. Автор даёт краткий обзор WTL, описывает процесс её установки, а затем объясняет базовые средства поддержки оконного интерфейса: иерархию оконных классов, циклы сообщений и карты сообщений.
.
А ещё про это можешь спросить отдельным топиком — ответят, может даже флейм разгориться..
Просто меня совратили однажды в сторону WTL/WinAPI, так что теперь я на MFC очень не заглядываюсь... хотя может быть зря — а то попаду куда-нибудь, скажут: знание MFC обязательно... Хотя щас больше смотрю в сторону .NET — вроде как за этим будущее.
Re[11]: Чья вина?
От: SergH Россия  
Дата: 03.04.02 14:40
Оценка: 1 (1)
Здравствуйте Dancer, Вы писали:

D>Последний ответ — я там написал, в чем дело. Не висела в ожидании, но и завершаться не хотела. А строчку действительно пришлось убрать.


Так не бывает. Либо функция возвращает управление, либо нет. К WaitForSingleObject это тоже относится. Попробуй вставить MessageBox после WairForsingleObject. Если он появится, значит действительно не висит.
Делай что должно, и будь что будет
Re: Чья вина?
От: adontz Грузия http://adontz.wordpress.com/
Дата: 03.04.02 15:18
Оценка: 1 (1)
Здравствуйте Dancer, Вы писали:

D>Ситуация такая: при попытке повторно отлинковать проект, VC выдае ошибку "нет доступа к файлу .exe". Попробовал удалить вручную — "файл используется Windows" и действительно нет доступа. Причем доступ появляется после перезагрузки, но исчезает после первой же линковки или через несколько раз. Я со страху переставил VC, а потом и винды, да толку никакого. Но этот эффект появился, когда я стал запускать отдельный поток для вычислений, хотя он у меня должен завершаться до завершения программы. Может в этом быть виновата моя программа или это глюк среды VC или виндов?


Это ваш глюк
Программа не завершается, а доступ к файлу с исполняющимся exe запрещён
Посмотри список процессов — увидишь.
На выходе убивай поток TerminateThread, так, на всякий случай.
Ну и log off тоже поможет (не только restart)
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[2]: Чья вина?
От: Polosaty Беларусь  
Дата: 03.04.02 15:57
Оценка: 1 (1)
Здравствуйте adontz, Вы писали:

A>Здравствуйте Dancer, Вы писали:


A>На выходе убивай поток TerminateThread, так, на всякий случай.

Настоятельно не рекомендуется так делать, поток должен завершаться корректно. А с остальным согласен. Проблема в том, что не завершается поток и, следовательно, процесс. И не забывайте делать CloseHandle, правила хорошего тона все-таки стОит соблюдать.
Чья вина?
От: Dancer Россия  
Дата: 03.04.02 06:10
Оценка:
Ситуация такая: при попытке повторно отлинковать проект, VC выдае ошибку "нет доступа к файлу .exe". Попробовал удалить вручную — "файл используется Windows" и действительно нет доступа. Причем доступ появляется после перезагрузки, но исчезает после первой же линковки или через несколько раз. Я со страху переставил VC, а потом и винды, да толку никакого. Но этот эффект появился, когда я стал запускать отдельный поток для вычислений, хотя он у меня должен завершаться до завершения программы. Может в этом быть виновата моя программа или это глюк среды VC или виндов?
Re: Чья вина?
От: ioni Россия  
Дата: 03.04.02 06:14
Оценка:
Здравствуйте Dancer, Вы писали:

D>Ситуация такая: при попытке повторно отлинковать проект, VC выдае ошибку "нет доступа к файлу .exe". Попробовал удалить вручную — "файл используется Windows" и действительно нет доступа. Причем доступ появляется после перезагрузки, но исчезает после первой же линковки или через несколько раз. Я со страху переставил VC, а потом и винды, да толку никакого. Но этот эффект появился, когда я стал запускать отдельный поток для вычислений, хотя он у меня должен завершаться до завершения программы. Может в этом быть виновата моя программа или это глюк среды VC или виндов?


а в taskmanager не смотрел небось тама болтается
Re[2]: Чья вина?
От: Dancer Россия  
Дата: 03.04.02 06:47
Оценка:
Здравствуйте iLYA , Вы писали:

I>Здравствуйте Dancer, Вы писали:


D>>Ситуация такая: при попытке повторно отлинковать проект, VC выдае ошибку "нет доступа к файлу .exe". Попробовал удалить вручную — "файл используется Windows" и действительно нет доступа. Причем доступ появляется после перезагрузки, но исчезает после первой же линковки или через несколько раз. Я со страху переставил VC, а потом и винды, да толку никакого. Но этот эффект появился, когда я стал запускать отдельный поток для вычислений, хотя он у меня должен завершаться до завершения программы. Может в этом быть виновата моя программа или это глюк среды VC или виндов?


I>Прю...

I>Неправильно закрываешь приложение. И у тебя остается процесс. Если работаешь под Win2000 запусти TaskManager, иначе из VS Tools ProcessView и увидешь, что твоя программа не закрылась
I>Попробуй у себя прописать так:

I>

I>        case WM_DESTROY:
I>            PostQuitMessage(0);
I>            break;
I>


I>Удачи,

I>iLYA

А где прописать?

The PostQuitMessage function indicates to the system that a thread has made a request to terminate (quit). It is typically used in response to a WM_DESTROY message.

C другой стороны
The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future.

Когда система посылает главному потоку WM_DESTROY он сам себе посылает WM_QUIT что ли?
Re: Чья вина?
От: Sergey Россия  
Дата: 03.04.02 07:36
Оценка:
Здравствуйте Dancer, Вы писали:

D>Ситуация такая: при попытке повторно отлинковать проект, VC выдае ошибку "нет доступа к файлу .exe". Попробовал удалить вручную — "файл используется Windows" и действительно нет доступа. Причем доступ появляется после перезагрузки, но исчезает после первой же линковки или через несколько раз. Я со страху переставил VC, а потом и винды, да толку никакого. Но этот эффект появился, когда я стал запускать отдельный поток для вычислений, хотя он у меня должен завершаться до завершения программы. Может в этом быть виновата моя программа или это глюк среды VC или виндов?


Или глюкофича антивируса. А вообще, посети www.sysinternals.com, там полно утилей, которые помогут определить, кто держит модуль/файл/etc.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[4]: Чья вина?
От: Dancer Россия  
Дата: 03.04.02 08:12
Оценка:
Здравствуйте Курилка, Вы писали:

К>Здравствуйте Dancer, Вы писали:


К><skip>

D>> А где прописать?

К>В оконной процедуре (WndProc)


D>>The PostQuitMessage function indicates to the system that a thread has made a request to terminate (quit). It is typically used in response to a WM_DESTROY message.


D>>C другой стороны

D>>The PostQuitMessage function posts a WM_QUIT message to the thread's message queue and returns immediately; the function simply indicates to the system that the thread is requesting to quit at some time in the future.

D>>Когда система посылает главному потоку WM_DESTROY он сам себе посылает WM_QUIT что ли?


К>WM_DESTROY посылается окну, а не потоку! Типа говорит, что окошко убито, всё — надо закругляться, соответственно, приложение делает последние завершающие действия и говорит: ок, закругляемся ( PostQuitMessage), и очередь сообщений убивается!


К>В моём представлении это примерно так выглядит


В книжке тоже написано, что из WndProc, но у меня dialog-based application, там нет такого! Могу сам создать обработчик WM_DESTROY и запихнуть туда вызов PostQuitMessage.
Re[5]: Чья вина?
От: Курилка Россия http://kirya.narod.ru/
Дата: 03.04.02 08:41
Оценка:
Здравствуйте Dancer, Вы писали:
D>В книжке тоже написано, что из WndProc, но у меня dialog-based application, там нет такого! Могу сам создать обработчик WM_DESTROY и запихнуть туда вызов PostQuitMessage.

Ну DialogProc-то есть? Туда пихай значит. Диалог — это же тоже по сути окно.
Re[6]: Чья вина?
От: Dancer Россия  
Дата: 03.04.02 09:21
Оценка:
Здравствуйте Курилка, Вы писали:

К>Здравствуйте Dancer, Вы писали:

D>>В книжке тоже написано, что из WndProc, но у меня dialog-based application, там нет такого! Могу сам создать обработчик WM_DESTROY и запихнуть туда вызов PostQuitMessage.

К>Ну DialogProc-то есть? Туда пихай значит. Диалог — это же тоже по сути окно.


Здесь НЕТ DialogProc, для всех событий есть просто обработчики. Я понимаю, что ламер, но не понимаю, о чем идет речь — в MSDN ссылка на CDialogImpl::DialogProc, а у меня просто class CFractalDlg : public CDialog и никаких шаблонов нет. Я посмотрел в Process Viewer — действительно, рабочий поток завершается, а процесс остается. Причем CDialog::OnCancel не хочет возвращать управление и повисает на закрывающей скобке.
Re[7]: Чья вина?
От: Курилка Россия http://kirya.narod.ru/
Дата: 03.04.02 09:53
Оценка:
Здравствуйте Dancer, Вы писали:

D>Здравствуйте Курилка, Вы писали:


К>>Здравствуйте Dancer, Вы писали:

D>>>В книжке тоже написано, что из WndProc, но у меня dialog-based application, там нет такого! Могу сам создать обработчик WM_DESTROY и запихнуть туда вызов PostQuitMessage.

К>>Ну DialogProc-то есть? Туда пихай значит. Диалог — это же тоже по сути окно.


D>Здесь НЕТ DialogProc, для всех событий есть просто обработчики. Я понимаю, что ламер, но не понимаю, о чем идет речь — в MSDN ссылка на CDialogImpl::DialogProc, а у меня просто class CFractalDlg : public CDialog и никаких шаблонов нет. Я посмотрел в Process Viewer — действительно, рабочий поток завершается, а процесс остается. Причем CDialog::OnCancel не хочет возвращать управление и повисает на закрывающей скобке.


Ясно — ты так и пиши, что на MFC делаешь, а то так сложно понять...
И соответственно — туда надо и постить.
Приведи, что у тебя в OnCancel?
Re[8]: Чья вина?
От: Dancer Россия  
Дата: 03.04.02 10:20
Оценка:
Здравствуйте Курилка, Вы писали:

К>Здравствуйте Dancer, Вы писали:


D>>Здравствуйте Курилка, Вы писали:


К>>>Здравствуйте Dancer, Вы писали:

D>>>>В книжке тоже написано, что из WndProc, но у меня dialog-based application, там нет такого! Могу сам создать обработчик WM_DESTROY и запихнуть туда вызов PostQuitMessage.

К>>>Ну DialogProc-то есть? Туда пихай значит. Диалог — это же тоже по сути окно.


D>>Здесь НЕТ DialogProc, для всех событий есть просто обработчики. Я понимаю, что ламер, но не понимаю, о чем идет речь — в MSDN ссылка на CDialogImpl::DialogProc, а у меня просто class CFractalDlg : public CDialog и никаких шаблонов нет. Я посмотрел в Process Viewer — действительно, рабочий поток завершается, а процесс остается. Причем CDialog::OnCancel не хочет возвращать управление и повисает на закрывающей скобке.


К>Ясно — ты так и пиши, что на MFC делаешь, а то так сложно понять...

К>И соответственно — туда надо и постить.
К>Приведи, что у тебя в OnCancel?

void CFractalDlg::OnCancel()
{
// TODO: Add extra cleanup here
if(m_flag==1)
{
g_eventKill.SetEvent();//Это прерывает выполнение цикла в рабочем потоке
::WaitForSingleObject(g_eventFinished, INFINITE);//А это так, типа рабочий поток из цикла вышел
//и сейчас завершится
}

CDialog::OnCancel();
//PostQuitMessage(0);//Со страху сюда поставил сначала, потом в OnDestroy() поробовал — все равно не работает
}
Re[9]: Чья вина?
От: Курилка Россия http://kirya.narod.ru/
Дата: 03.04.02 10:33
Оценка:
Здравствуйте Dancer, Вы писали:

D>Здравствуйте Курилка, Вы писали:


К>>Здравствуйте Dancer, Вы писали:


D>>>Здравствуйте Курилка, Вы писали:


К>>>>Здравствуйте Dancer, Вы писали:

D>>>>>В книжке тоже написано, что из WndProc, но у меня dialog-based application, там нет такого! Могу сам создать обработчик WM_DESTROY и запихнуть туда вызов PostQuitMessage.

К>>>>Ну DialogProc-то есть? Туда пихай значит. Диалог — это же тоже по сути окно.


D>>>Здесь НЕТ DialogProc, для всех событий есть просто обработчики. Я понимаю, что ламер, но не понимаю, о чем идет речь — в MSDN ссылка на CDialogImpl::DialogProc, а у меня просто class CFractalDlg : public CDialog и никаких шаблонов нет. Я посмотрел в Process Viewer — действительно, рабочий поток завершается, а процесс остается. Причем CDialog::OnCancel не хочет возвращать управление и повисает на закрывающей скобке.


К>>Ясно — ты так и пиши, что на MFC делаешь, а то так сложно понять...

К>>И соответственно — туда надо и постить.
К>>Приведи, что у тебя в OnCancel?

D>void CFractalDlg::OnCancel()

D>{
D> // TODO: Add extra cleanup here
D> if(m_flag==1)
D> {
D> g_eventKill.SetEvent();//Это прерывает выполнение цикла в рабочем потоке
D> ::WaitForSingleObject(g_eventFinished, INFINITE);//А это так, типа рабочий поток из цикла вышел
D> //и сейчас завершится
D> }
D>
D> CDialog::OnCancel();
D> //PostQuitMessage(0);//Со страху сюда поставил сначала, потом в OnDestroy() поробовал — все равно не работает
D>}

признаюсь — MFC не люблю и знаю не очень...
запости в тему MFC,
кстати, PostQuitMessage, по ходу, тебе не нужен,
у тебя оба потока убиваются? Такое впечатление, что в них дело...
в твойApp.InitInstance твойDlg.DoModal проходит?
Re[10]: Чья вина?
От: Dancer Россия  
Дата: 03.04.02 13:54
Оценка:
Здравствуйте Курилка, Вы писали:

К>Здравствуйте Dancer, Вы писали:


D>>Здравствуйте Курилка, Вы писали:


К>>>Здравствуйте Dancer, Вы писали:


D>>>>Здравствуйте Курилка, Вы писали:


К>>>>>Здравствуйте Dancer, Вы писали:

D>>>>>>В книжке тоже написано, что из WndProc, но у меня dialog-based application, там нет такого! Могу сам создать обработчик WM_DESTROY и запихнуть туда вызов PostQuitMessage.

К>>>>>Ну DialogProc-то есть? Туда пихай значит. Диалог — это же тоже по сути окно.


D>>>>Здесь НЕТ DialogProc, для всех событий есть просто обработчики. Я понимаю, что ламер, но не понимаю, о чем идет речь — в MSDN ссылка на CDialogImpl::DialogProc, а у меня просто class CFractalDlg : public CDialog и никаких шаблонов нет. Я посмотрел в Process Viewer — действительно, рабочий поток завершается, а процесс остается. Причем CDialog::OnCancel не хочет возвращать управление и повисает на закрывающей скобке.


К>>>Ясно — ты так и пиши, что на MFC делаешь, а то так сложно понять...

К>>>И соответственно — туда надо и постить.
К>>>Приведи, что у тебя в OnCancel?

D>>void CFractalDlg::OnCancel()

D>>{
D>> // TODO: Add extra cleanup here
D>> if(m_flag==1)
D>> {
D>> g_eventKill.SetEvent();//Это прерывает выполнение цикла в рабочем потоке
D>> ::WaitForSingleObject(g_eventFinished, INFINITE);//А это так, типа рабочий поток из цикла вышел
D>> //и сейчас завершится
D>> }
D>>
D>> CDialog::OnCancel();
D>> //PostQuitMessage(0);//Со страху сюда поставил сначала, потом в OnDestroy() поробовал — все равно не работает
D>>}

К>признаюсь — MFC не люблю и знаю не очень...

К>запости в тему MFC,
К>кстати, PostQuitMessage, по ходу, тебе не нужен,
К>у тебя оба потока убиваются? Такое впечатление, что в них дело...
К>в твойApp.InitInstance твойDlg.DoModal проходит?

Если интересно, я разобрался, в чем было дело. Потрясающе: коментнул одну строчку в OnCancel — и заработало!
void CFractalDlg::OnCancel()
{ if(m_flag==1)
{
g_eventKill.SetEvent();
//::WaitForSingleObject(g_eventFinished, INFINITE);
}

CDialog::OnCancel();
}
Фишка в том, что это событие должен был инициализировать рабочий поток непосредственно перед тем, как завершиться, чтобы я точно знал, что вычисления закончены. И все так и было, WaitForSingleObject возвращало управление, но процесс НЕ завершался. Интересно, почему так? Ведь он не "повисал" на этом месте!

А MFC почему не любишь? Интересно мнение человека, который может сравнивать, исходя из собственного опыта.
Re[10]: Чья вина?
От: Dancer Россия  
Дата: 03.04.02 14:09
Оценка:
Здравствуйте SergH, Вы писали:

SH>Здравствуйте Dancer, Вы писали:



D>>void CFractalDlg::OnCancel()

D>>{
D>> // TODO: Add extra cleanup here
D>> if(m_flag==1)
D>> {
D>> g_eventKill.SetEvent();//Это прерывает выполнение цикла в рабочем потоке
D>> ::WaitForSingleObject(g_eventFinished, INFINITE);//А это так, типа рабочий поток из цикла вышел
D>> //и сейчас завершится
D>> }
D>>
D>> CDialog::OnCancel();
D>> //PostQuitMessage(0);//Со страху сюда поставил сначала, потом в OnDestroy() поробовал — все равно не работает
D>>}

SH>PostQuitMessage(0) в данном случае не причём. 99% — ты висишь в ожидании установки g_eventFinished. Просто убери строчку с WaitForSingleObject(...) и программа будет завершаться. Если "просто убирать" не хочется, проверь, что рабочий поток действительно завершается при установке g_eventKill и что перед смертью он действительно устанавливает g_eventFinished. Если бы это был API, вместо g_eventFinished можно было бы ждать освобождения описателя потока, он освобождается при завершении потока. MFC я знаю хуже, но думаю тоже можно.


Последний ответ — я там написал, в чем дело. Не висела в ожидании, но и завершаться не хотела. А строчку действительно пришлось убрать.
Re[3]: handle
От: Dancer Россия  
Дата: 05.04.02 04:37
Оценка:
Здравствуйте Polosaty, Вы писали:

P>Здравствуйте adontz, Вы писали:


A>>Здравствуйте Dancer, Вы писали:


A>>На выходе убивай поток TerminateThread, так, на всякий случай.

P>Настоятельно не рекомендуется так делать, поток должен завершаться корректно. А с остальным согласен. Проблема в том, что не завершается поток и, следовательно, процесс. И не забывайте делать CloseHandle, правила хорошего тона все-таки стОит соблюдать.

А что, разве когда объект CWinThread уничтожается, его handle не освобождается автоматически? И вообще, по-русски handle — это что (переводится вроде как "описатель")? И чем функционально отличается от указателя на объект? Многие ф-ции типа GetExitCodeThread принимают в качестве параметра, идентифицирующего объект, его handle, а не указатель. Почему?
Re[5]: handle
От: Dancer Россия  
Дата: 05.04.02 06:34
Оценка:
Здравствуйте Polosaty, Вы писали:

P>Здравствуйте Dancer, Вы писали:


D>>Здравствуйте Polosaty, Вы писали:


P>>>Здравствуйте adontz, Вы писали:


A>>>>Здравствуйте Dancer, Вы писали:


A>>>>На выходе убивай поток TerminateThread, так, на всякий случай.

P>>>Настоятельно не рекомендуется так делать, поток должен завершаться корректно. А с остальным согласен. Проблема в том, что не завершается поток и, следовательно, процесс. И не забывайте делать CloseHandle, правила хорошего тона все-таки стОит соблюдать.

D>>А что, разве когда объект CWinThread уничтожается, его handle не освобождается автоматически?

P>Так сложилось, что я не использую MFC для программирования потоков. Поэтому мне приходится делать CloseHandle ручками. Если его делает MFC — на здоровье.
P>Кстати, закрытие хэндла с помощью CloseHandle и освобождение хэндла — не одно и то же с точки зрения ОС. Главное, что делает CloseHandle — декремент счетчика привязок объекта. Это не означает, что хэндл будет освобожден тут же. Хэндл освобождается, когда счетчик привязок станет равным нулю (т.е. когда все потоки, пользующие, например, семафор, сделают CloseHandle, или когда все потоки, получившие каким-то образом хэндл другого потока, т.е. икрементировавшие счетчик привязок объекта, сделают CloseHandle и сам поток завершится и т.д.)

D>>И вообще, по-русски handle — это что (переводится вроде как "описатель")? И чем функционально отличается от указателя на объект? Многие ф-ции типа GetExitCodeThread принимают в качестве параметра, идентифицирующего объект, его handle, а не указатель. Почему?

P>Хэндл функционально действительно подобен указателю, но имеет дополнительные свойства. Главные из дополнительных свойств таковы:
P>1) указатель актуален в пределах адресного пространства одного процесса, ну а хэндл можно пользовать (если грамотно) в разных процессах, в т.ч. наследовать. Правда, при этом в разных процессах значение одного и того же хэндла может быть разным;
P>2) хэндл может быть актуален даже тогда, когда описываемый им объект (как ты правильно заметил, хэндл по-русски — описатель) перестал существовать (например, когда поток завершился, хэндл может быть еще не освобожден и с его помощью можно получит код возврата потока).

P>Хэндл — это описатель объекта ядра ОС. Каждый объект ядра имеет структуру, его описывающую, которая, в частности, включает и счетчик привязок. Используя для доступа к объекту ядра хэндл и функции API, программер не должен думать и не может забыть об инкременте или декременте счетчика привязок, об удалении объекта ядра, если его счетчик привязок стал равен 0 и т.д.


P>Ну а на самом деле хэндл — это индекс в таблице процесса, которая содержит указатели на эти самые структуры, описывающие объекты ядра. Структура этой таблицы — закрытая информация, но ее можно представлять себе так. В таблице присутствуют 4 столбца:

P>1. индекс (т.е. значение хэндла);
P>2. указатель на блок памяти ядра (т.е. ту самую структуру, описывающую объект ядра);
P>3. маска доступа;
P>4. набор битовых флагов.

P>Вообще, лучше всего на эту тему почитать Рихтера. Собственно, практически вся привденная мной информация взята оттуда.


Спасибо, круто!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.