Чья вина?
От: 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: Чья вина?
От: 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[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[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[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[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[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[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[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, правила хорошего тона все-таки стОит соблюдать.
Re[3]: handle
От: Dancer Россия  
Дата: 05.04.02 04:37
Оценка:
Здравствуйте Polosaty, Вы писали:

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


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


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

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

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