Ситуация такая: при попытке повторно отлинковать проект, VC выдае ошибку "нет доступа к файлу .exe". Попробовал удалить вручную — "файл используется Windows" и действительно нет доступа. Причем доступ появляется после перезагрузки, но исчезает после первой же линковки или через несколько раз. Я со страху переставил VC, а потом и винды, да толку никакого. Но этот эффект появился, когда я стал запускать отдельный поток для вычислений, хотя он у меня должен завершаться до завершения программы. Может в этом быть виновата моя программа или это глюк среды VC или виндов?
Здравствуйте Dancer, Вы писали:
D>Ситуация такая: при попытке повторно отлинковать проект, VC выдае ошибку "нет доступа к файлу .exe". Попробовал удалить вручную — "файл используется Windows" и действительно нет доступа. Причем доступ появляется после перезагрузки, но исчезает после первой же линковки или через несколько раз. Я со страху переставил VC, а потом и винды, да толку никакого. Но этот эффект появился, когда я стал запускать отдельный поток для вычислений, хотя он у меня должен завершаться до завершения программы. Может в этом быть виновата моя программа или это глюк среды VC или виндов?
Здравствуйте Dancer, Вы писали:
D>Ситуация такая: при попытке повторно отлинковать проект, VC выдае ошибку "нет доступа к файлу .exe". Попробовал удалить вручную — "файл используется Windows" и действительно нет доступа. Причем доступ появляется после перезагрузки, но исчезает после первой же линковки или через несколько раз. Я со страху переставил VC, а потом и винды, да толку никакого. Но этот эффект появился, когда я стал запускать отдельный поток для вычислений, хотя он у меня должен завершаться до завершения программы. Может в этом быть виновата моя программа или это глюк среды VC или виндов?
Прю...
Неправильно закрываешь приложение. И у тебя остается процесс. Если работаешь под Win2000 запусти TaskManager, иначе из VS Tools ProcessView и увидешь, что твоя программа не закрылась
Попробуй у себя прописать так:
Здравствуйте 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 что ли?
Здравствуйте Dancer, Вы писали:
D>Ситуация такая: при попытке повторно отлинковать проект, VC выдае ошибку "нет доступа к файлу .exe". Попробовал удалить вручную — "файл используется Windows" и действительно нет доступа. Причем доступ появляется после перезагрузки, но исчезает после первой же линковки или через несколько раз. Я со страху переставил VC, а потом и винды, да толку никакого. Но этот эффект появился, когда я стал запускать отдельный поток для вычислений, хотя он у меня должен завершаться до завершения программы. Может в этом быть виновата моя программа или это глюк среды VC или виндов?
Или глюкофича антивируса. А вообще, посети www.sysinternals.com, там полно утилей, которые помогут определить, кто держит модуль/файл/etc.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
В оконной процедуре (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), и очередь сообщений убивается!
Здравствуйте Курилка, Вы писали:
К>Здравствуйте 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.
Здравствуйте Dancer, Вы писали: D>В книжке тоже написано, что из WndProc, но у меня dialog-based application, там нет такого! Могу сам создать обработчик WM_DESTROY и запихнуть туда вызов PostQuitMessage.
Ну DialogProc-то есть? Туда пихай значит. Диалог — это же тоже по сути окно.
Здравствуйте Курилка, Вы писали:
К>Здравствуйте Dancer, Вы писали: D>>В книжке тоже написано, что из WndProc, но у меня dialog-based application, там нет такого! Могу сам создать обработчик WM_DESTROY и запихнуть туда вызов PostQuitMessage.
К>Ну DialogProc-то есть? Туда пихай значит. Диалог — это же тоже по сути окно.
Здесь НЕТ DialogProc, для всех событий есть просто обработчики. Я понимаю, что ламер, но не понимаю, о чем идет речь — в MSDN ссылка на CDialogImpl::DialogProc, а у меня просто class CFractalDlg : public CDialog и никаких шаблонов нет. Я посмотрел в Process Viewer — действительно, рабочий поток завершается, а процесс остается. Причем CDialog::OnCancel не хочет возвращать управление и повисает на закрывающей скобке.
Здравствуйте 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?
Здравствуйте Курилка, Вы писали:
К>Здравствуйте 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() поробовал — все равно не работает
}
Здравствуйте 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 проходит?
Здравствуйте Курилка, Вы писали:
К>Здравствуйте 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 почему не любишь? Интересно мнение человека, который может сравнивать, исходя из собственного опыта.
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 я знаю хуже, но думаю тоже можно.
Здравствуйте Dancer, Вы писали: D>А MFC почему не любишь? Интересно мнение человека, который может сравнивать, исходя из собственного опыта.
Какой там опыт — мне ещё программить и программить до настоящего программиста, зелёные мы...
Поэтому своих мыслей про MFC приводить не буду, глянь вот лучше сюда
.
А ещё про это можешь спросить отдельным топиком — ответят, может даже флейм разгориться..
Просто меня совратили однажды в сторону WTL/WinAPI, так что теперь я на MFC очень не заглядываюсь... хотя может быть зря — а то попаду куда-нибудь, скажут: знание MFC обязательно... Хотя щас больше смотрю в сторону .NET — вроде как за этим будущее.
Здравствуйте 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 я знаю хуже, но думаю тоже можно.
Последний ответ — я там написал, в чем дело. Не висела в ожидании, но и завершаться не хотела. А строчку действительно пришлось убрать.
Здравствуйте Dancer, Вы писали:
D>Последний ответ — я там написал, в чем дело. Не висела в ожидании, но и завершаться не хотела. А строчку действительно пришлось убрать.
Так не бывает. Либо функция возвращает управление, либо нет. К WaitForSingleObject это тоже относится. Попробуй вставить MessageBox после WairForsingleObject. Если он появится, значит действительно не висит.
Здравствуйте Dancer, Вы писали:
D>Ситуация такая: при попытке повторно отлинковать проект, VC выдае ошибку "нет доступа к файлу .exe". Попробовал удалить вручную — "файл используется Windows" и действительно нет доступа. Причем доступ появляется после перезагрузки, но исчезает после первой же линковки или через несколько раз. Я со страху переставил VC, а потом и винды, да толку никакого. Но этот эффект появился, когда я стал запускать отдельный поток для вычислений, хотя он у меня должен завершаться до завершения программы. Может в этом быть виновата моя программа или это глюк среды VC или виндов?
Это ваш глюк
Программа не завершается, а доступ к файлу с исполняющимся exe запрещён
Посмотри список процессов — увидишь.
На выходе убивай поток TerminateThread, так, на всякий случай.
Ну и log off тоже поможет (не только restart)
Здравствуйте adontz, Вы писали:
A>Здравствуйте Dancer, Вы писали:
A>На выходе убивай поток TerminateThread, так, на всякий случай.
Настоятельно не рекомендуется так делать, поток должен завершаться корректно. А с остальным согласен. Проблема в том, что не завершается поток и, следовательно, процесс. И не забывайте делать CloseHandle, правила хорошего тона все-таки стОит соблюдать.
Здравствуйте Polosaty, Вы писали:
P>Здравствуйте adontz, Вы писали:
A>>Здравствуйте Dancer, Вы писали:
A>>На выходе убивай поток TerminateThread, так, на всякий случай. P>Настоятельно не рекомендуется так делать, поток должен завершаться корректно. А с остальным согласен. Проблема в том, что не завершается поток и, следовательно, процесс. И не забывайте делать CloseHandle, правила хорошего тона все-таки стОит соблюдать.
А что, разве когда объект CWinThread уничтожается, его handle не освобождается автоматически? И вообще, по-русски handle — это что (переводится вроде как "описатель")? И чем функционально отличается от указателя на объект? Многие ф-ции типа GetExitCodeThread принимают в качестве параметра, идентифицирующего объект, его handle, а не указатель. Почему?