![]() |
|
|
![]()
|
|
| ksili |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: 1 Всего: 17 |
У меня один коротенький поток вызывается главным окном каждые 2 секунды. Логично освобождать из-под него память. Однако если FreeOnTerminate = true, то возникает исключение примерно такого содержания:
"... raised exception class EOSError with message 'System Error. Code: 6. Неверный дескриптор'". Прямо так по-русски и пишет - неверный дескриптор. В классе потока есть три перменные, но я вроде к ним нигде кроме как из самого потока не обращаюсь, тем более после его завершения. В чём может быть проблема? Что это за класс EOSError? -------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
|||
|
||||
| Vyacheslav |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 47 Всего: 59 |
А после того, как отрабатывает, Вы его заново создаете? -------------------- С уважением, Вячеслав Ермолаев |
|||
|
||||
| ksili |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: 1 Всего: 17 |
Создаю его по событию таймера. Событие возникает каждые 3 секунды (а не 2 как раньше написал, извиняюсь). За это время он успевает завершиться.
Но это наверно неважно, так как возникает исключение на первом же экземпляре потока (только не знаю именно в момент завершения или нет). А вообще если он не успеет завершиться за 3 сек. И по таймеру будет создан второй поток, он не будет конфликтоватьс первым? Или это будет неправильно? Это сообщение отредактировал(а) ksili - 12.3.2007, 11:13 -------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
|||
|
||||
| Vyacheslav |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 47 Всего: 59 |
Без кода врядли что можно сказать путное
-------------------- С уважением, Вячеслав Ермолаев |
|||
|
||||
| ama_kid |
|
|||
![]() АСУТП-кодер ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1460 Регистрация: 5.3.2007 Где: Москва Репутация: 10 Всего: 95 |
Код, конечно, в таких вопросах ОБЯЗАТЕЛЬНО надо приводить... Навскидку можно предположить, что при завершении потока вызывается последовательность Thread1->Terminate и затем Thread1->Free (или как-то аналогично). При установленном свойстве FreeOnTerminate = true вторая команда фактически будет освобождать уже автоматически особожденный (при Terminate) участок памяти, что приводит к AV.
-------------------- самурай без меча подобен самураю с мечом, но только без меча |
|||
|
||||
| ksili |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: 1 Всего: 17 |
Посмотрел в диспетчере задач без FreeOnTerminate = true. Вроде всё нормально один процесс создаётся и через некоторое время убивается. Память тоже освобождается и выделяется (больше не становится). Так что ложная тревога. Всем спасибо за внимание
-------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
|||
|
||||
| Vyacheslav |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 47 Всего: 59 |
А причем тут процессы Правда по завершению программы конечно все освободится ( WIn32 как никак Добавлено @ 13:21 Это Вы по диспетчеру задач определили ? Мда. А Вы не пробовали спросить мнение на этот счет у CodeGuard? Думаю, он будет против. -------------------- С уважением, Вячеслав Ермолаев |
|||
|
||||
| ksili |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: 1 Всего: 17 |
Так значит правильная последовательность работы с потоком примерно такая:
? Если так написать, то память будет освобождаться и на флаг FreeOnTerminate можно не обращать внимание? Я правильно понял? Это сообщение отредактировал(а) ksili - 13.3.2007, 07:37 -------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
|||
|
||||
| pandrew |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 213 Регистрация: 27.3.2006 Репутация: 3 Всего: 3 |
Для потока с FreeOnTerminate = true; завершение делается так:
Видимо если FreeOnTerminate = false; надо добавить delete td; |
|||
|
||||
| Vyacheslav |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 47 Всего: 59 |
Идея то правильная. И тут все будет очищаться правильно. Только в с логикой напряги. Вы запускаете поток, а потом тормозите основной до момента, пока не выполнится дочерний. Смысл? Не проще тогда выполнить все действия в основном потоке? Все равно при работе дочернего он простаивает Я пока не могу понять одно. Почему у Вас не работает это ?
Вы случаем после этих строчек не пытаетесь написать что-то вроде
или то, что pandrew указал? Этого делать ни в коем случае нельзя. К моменту обращения к объекту td после того как уже вызван Resume() поток может выполнится, а объект, соответственно, уничтожен и Вы будете обращаться к несуществуещему объекту Добавлено @ 13:17 Грубая ошибка. Во-первых к моменту вызова Terminate поток может уже завершиться и td уничтожиться. Во-вторых, даже если поток еще работает, то он может успеть завершиться и уничтожиться после Terminate, но до вызова WaitFor. -------------------- С уважением, Вячеслав Ермолаев |
||||||
|
|||||||
| ksili |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: 1 Всего: 17 |
Сейчас уже кода перед глазами нет, завтра погляжу повнимательнее и отвечу.
А почему нельзя после Resume() писать WaitFor()? Когда вообще тогда WaitFor() писать нужно? -------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
|||
|
||||
| dumb |
|
|||
![]() sceloglauxalbifacies ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2929 Регистрация: 16.6.2006 Репутация: 32 Всего: 158 |
ksili, сможешь аргументировать применение потоков в своей задаче?
|
|||
|
||||
| ksili |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: 1 Всего: 17 |
Я согласен, что WaitFor использовать в основном потоке неправильно, так как это тормозит всю прогу и сводит на нет все преимущество от использования потоков.
Теперь попробую аргументировать применение потоков в моей задаче. В системе есть много COM-портов. Программа должна опрашивать те которые инициализированы (сейчас при отладке экспериментирую только с одним) на предмет того, что на них что-то поступило. Если поступило, то она сохраняет инфу об этом в специальной таблице БД. Есть ещё несколько потоков, которые периодически смотрят в эту таблицу и если там что-то есть, то отрабатывают это событие. То событие таймера (раз в 3 сек) о котором я говорил выше, перебирает все порты и запускает для каждого инициализированного порта поток, к-рый его опрашивает. В общем эти действия (опрос порта и обработка поступившей инфы) должна происходить не в основном потоке (реально портов будет не меньше 40), чтобы я во время всего этого мог работать с программой: инициализировать порт, освободить порт, смотреть журналы портов, смотреть текущую информацию о каналах и т.д. Я сейчас уже подумал, что правильнее будет не создавать эти потоки каждые 3 секунды, а создавать поток на каждый инициализированный порт, который будет его опрашивать постоянно:
Это сообщение отредактировал(а) ksili - 14.3.2007, 06:01 -------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
|||
|
||||
| Valeri |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 2.2.2007 Репутация: нет Всего: нет |
Привет
у меня примерно такая же задача, но порт всего один. смысл тот же - время от времени для передачи в порт данных требуется приостановить поток сбора данных из порта. Сделал поток именно так как указано в предыдущем посте. Но не пойму почему не удается подвесить поток на время передачи в порт. Программа виснет. сам поток в таком виде работает нормально: while(!Terminated) { if(WaitCommEvent(Form1->hCom,&dwCommEvent,NULL)) if(ClearCommError(Form1->hCom,&dwError,&COMSTAT)) dwRead=COMSTAT.cbInQue; { while (dwRead) { ReadFile(Form1-hCom lpBuffer1,dwRead,lpNumberOfBytesWritten, NULL); Form1->Nsect=Form1->Data.RecByte1 Form1->Fh=(Form1->Data.RecByte2)+((Form1->Data.RecByte3)*255); Form1->Label20->Caption=IntToStr(Form1->Data.RecByte1); Form1->Label21->Caption=IntToStr(Form1->Data.RecByte2); Form1->Label23->Caption=IntToStr(Form1->Data.RecByte3); Form1->Label24->Caption=IntToStr(Form1->Fh); } } } но при попытке его подвесить из основного потока все виснет. |
|||
|
||||
| ksili |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2069 Регистрация: 3.11.2005 Где: Красноярск Репутация: 1 Всего: 17 |
Всё, что обращается к основной форме
надо поместить в отдельную функцию класса потока и вызывать её при помощи метода потока Synchronize. посмотри хелп на Synchronize -------------------- Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с) |
|||
|
||||
![]()
|
| Правила форума "С++ Builder" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C++ Builder | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |