| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > Открываю файл -> операционка виснет |
| Автор: neosapient 19.12.2006, 00:10 | ||
| Здравствуйте. Возникла проблема на ровном месте, немогу понять откуда лезет. Задача. Открыть файл, считать оттуда данные определенной структуры, закрыть файл. Решешал задачку так: Создал диалог. В момент прихода сообщения WM_INITDIALOG создается дополнительный поток AnalysFile(...). В этой функции открываю файл test.txt на чтение побайтно. Создаю заполняемую структуру и указатель на нее. Далее пока файл не кончиться, заполняю побайтно через указатель все поля структуры. По окончании файла, закрываю соединение. Дополнительный поток закрываеться.
Ну в общем начинаю я работать с дебагером, то все нормально отрабатывает,а то винда виснет, только мышка по экрану двигается. Подскажите, ЧТО не так делаю. Доп. вопрос: когда происходит считывание байтов из файла и их побайтная запись в структуру, то создается такое впечатление, что char у меня в два байта?! В том смысле, что при i равном 1 из файла считывается значение b однако оно пишется в сокрытую область стуктуры. Может происходит какое то выравнивание длинны структуры до значения кратного 4 байтам? |
| Автор: Earnest 19.12.2006, 08:58 |
| Нехорошо прерывать поток через TerminateThread. Это для аварийного прерывания, когда поток не отвечает. При этом не освобождаются ресурсы и не происходят другие правильные вещи. Для такой маленькой программы как твоя, это, возможно и ерунда, но для реальных проектов - отнюдь нет. Поток должен завершаться сам. Для того чтобы завершить его извне, нужно создать, например, событие (event). Управляющий поток сигнализирует событие, а рабочий поток должен в своем цикле отслеживать, не активно ли событие, и завершаться, если это так. Кроме того, поток вполне может завершить до того, как ты нажмешь Cancel. И это тоже нужно проверять. |
| Автор: neosapient 19.12.2006, 09:06 |
| За "выравние полей" спасибо, не знал. А по поводу основного вопроса: Если я создаю доп поток не на сообщение WM_INITDIALOG, а на WM_COMMAND -> IDOK, то ничего не виснет. Щелкаю на кнопочку ОК и доп поток запускается. Но мне хочется создавать доп поток на сообщение WM_INITDIALOG |
| Автор: Aleksandor 19.12.2006, 16:12 |
| Кажись читал у Рихтера что нельзя пользовать CreateThread если используются функции run-time. Чтение из файла тоже как-то странно оформлено, имхо. |
| Автор: neosapient 23.12.2006, 21:45 | ||
Aleksandor, извени, а что относиться к run-time функциям? и на что их заменить?..
Ну, функции взяты из stdio.h |
| Автор: Aleksandor 23.12.2006, 22:27 |
| Щас посмотрел, у диалоговой процедуры нет родительского окна. Процедура диалоговая и WinMain как-бы в одном стакане. Мне кажется это не есть хорошо. Run-time функции это те самые fopen, getc, time, strchr и т.д. Вместо CreateThread лучше заюзать _beginthreadex Почему-ищи в MSDN по слову _beginthreadex Насчет странного это чтение из файла побайтово-это слишком неэффективно. Кстати, в файле может и не быть feof. Тогда чтение зависнет навеки веков Лучше читать сразу весь файл или какую-то его часть в буфер, а потом анализировать. Или сделать file mapping - тогда и буфер не нужен. |
| Автор: neosapient 24.12.2006, 22:27 | ||||
Ну попытался разделить... Создаю окно, делаю дочерний диалог, делаю поток. Все работает. Второй эксперимент - Создаю окно, делаю дочерний диалог и показываю, делаю поток. Все виснет. (этот пример в приложении) Подозрение на прорисовку окна. Как исправлять?
Угу, так и есть, поставил временную заглушку. |
| Автор: Aleksandor 25.12.2006, 00:08 |
| Вот, у меня вроде пашет... |
| Автор: oper54 25.12.2006, 12:07 | ||
по поводу вот этого... надо под твои данные глобально выделять память GlobalAlloc, и тогда не надо будет ни каких смещений указывать, и все потоки нормально будут работать с этим отрезком памяти... хотя с прагмами тоже вариант, если не хо с памятью морочится... =) ИМХО по меньше пользоватся надо дерективами компилера, ибо не у всех компилеров они такие есть =) |
| Автор: neosapient 25.12.2006, 21:37 | ||
Aleksandor, а ты поставь брякпоинт на начало функции AnalysFile и будет тебе "шастъе" В общем пока не пашет... oper54, данные структурированы и я честно говоря не предсталяю как тут применить GlobalAlloc, вместо выравнивания полей. Поясни примером, что имелось в виду... |
| Автор: Aleksandor 25.12.2006, 22:04 |
| Я конешно сильно извиняюсь... Но... зачем ставить breakpoint на начале AnalyseFile |
| Автор: neosapient 25.12.2006, 22:29 | ||
Чтоб, проверить правильность работы... И вообще надо чтоб в любой части программы можно было ставить breakpoint, чтоб контролировать правильность работы. А то как разобраться с кодом черного ящика... |
| Автор: Aleksandor 25.12.2006, 22:37 |
| Не обязательно |
| Автор: neosapient 25.12.2006, 22:45 | ||
А как контролировать поля структур далее??? |
| Автор: Aleksandor 25.12.2006, 22:54 |
| Ну например распечатать в файл их значения, или сравнить с образцом или посмотреть в отладчике... |
| Автор: neosapient 26.12.2006, 09:03 |
| И я про это, а отладчик виснет вместе с операционкой |
| Автор: Aleksandor 26.12.2006, 15:41 |
| Может что с отладчиком? Прога простейшая, там и виснуть то нечему |
| Автор: neosapient 26.12.2006, 16:10 | ||||
И я так счетаю, сократил все до нельзя, а баг остался.
У меня VC 7. Позже попробую на VC 6 (сейчас времени нет устанавливать). И как я понял при установке breakpiont`a на начале ф-ии AnalysFile, у тебя также виснет всё. |
| Автор: Aleksandor 26.12.2006, 16:32 | ||||
| Да ничего не виснет, даже с брейкпойнтом (я ваще ими не пользуюсь никогда) А если убрать вот этот кусок
тоже виснет? Попробуй без брейкпойнта, например так
|
| Автор: neosapient 26.12.2006, 18:55 |
| Я понял в чем проблема У меня стоит Norton AntiVirus (2004, но год не важен) Видать, недели полторы назад закачался updata, и теперь этот антивир отлавливает все подозрительные действия с потоками. Кстати, чтение из файла вообще не причем, освободил тушку AnalysFile (делал сразу ретурн), всеравно виснет. Отключаешь антивир, и все впорядке. Думаю, какой антивир поставить. Каспер еще три года назад начал выкидывать подобные трюки (я его тогда и снес). На руках есть NOD32 и F-Secure. Програмить под ними не пробовал, но склоняюсь к F-Secure. А какой антивир у тебя? Впрочем стоит сделать голосование "какой антивир не мешает программированию под Windows"... С этим вопросом все. |
| Автор: Aleksandor 26.12.2006, 21:46 |
| У меня вообще антивиря нет |
| Автор: neosapient 26.12.2006, 22:06 | ||
Я тоже так считаю. И делаю бекапы примерно раз в две недели... Ну да ладно... |