![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
потоки [D6, D7, WinXP]
Mixal__ © (2006-12-06 07:26:00)Добрый день. Вот такой вопрос профессионалам:
Есть программа создающая отдельный thread, в котором идёт опрос устройства(обращение к COM порту посредством ReadFile/WriteFile) через промежутки времени (sleep). В основной программе также есть обращения к этому устройству. Дело в том, что устройство может обработать последующий запрос только спустя некоторое время(время обработки запроса). Вызовы из потока могут наступить в любое время, когда ещё не обработан устройством вызов из главной программы. Каким образом можно исключить такую ситуацию?
Сергей М. (2006-12-11 10:55:00) [1]
> Эксперимент показал, что WaitForSingleObject не вернуло
> WAIT_TIMEOUT
Значит эта Wait-функция была вызвана заведомо не при финализации, а раньше.
Сергей М. (2006-12-11 10:53:00) [2]
> Что подразумевалось под финализацией длл?
Код в составе образа dll, вызываемый системой при выгрузке этой dll из АП процесса ее использующего.
Конкретно - вызов функции DllEntryPoint() с параметром PROCESS_DETACH.
> При инициализации dll создаётся поток
Соответственно контрвопрос - что здесь подразумевалось под инициализацией ?
> Деструктор вызывается когда пользователь закрывает программу
Что, сам по себе что ли вызывается ?
Т.е. ты сам не понимаешь, где в твоем коде происходит вызов этого деструктора ?
Mixal__ (2006-12-11 10:44:00) [3]Что подразумевалось под финализацией длл?
Я не в курсе как работает программа, подключающая длл. Деструктор вызывается когда пользователь закрывает программу.
Эксперимент показал, что WaitForSingleObject не вернуло WAIT_TIMEOUT...
Сергей М. (2006-12-11 09:36:00) [4]Ничего не понимаю ...
Сначала ты говоришь, что
> В деструкторе класса ( не при финализациидлл)
А теперь
> При финализациидлл этот деструктор выполняется
Вражескую разведку что ли запутываешь ?)
> почему код неработоспособен?
Потому что при финализации dll ты никогда не дождешься сигнала завершения потока, созданного в контексте этой dll.
Следы ведут к блокировке PEB, выполняемой системой всякий раз при загрузке/выгрузке модуля.
Mixal__ (2006-12-11 09:15:00) [5]При финализации длл этот деструктор выполняется... но почему код неработоспособен??
Сергей М. (2006-12-11 08:47:00) [6]
> В деструкторе класса (не при финализации длл)
Если не при финализации этот деструктор вызывается, то когда ?
Mixal__ (2006-12-11 08:03:00) [7]
> > Mixal__ (07.12.06 14:07) [36]
>
>
>
> > Контроль - это опрос разных датчиков.
> >
> > Вроде того: запустили вы программу - у вас в разных окошках
>
> > меняются всякие значения - ну допустим температура, давление,
>
> > скорость воздуха, уровень воды в баке итп. А нажали кнопку
>
> > - у вас хопа и включился насос итп.
>
>
> Понятно.
> Велосипед, значит, изобретаем)
>
> Почитай что-нть научно-популярное про уже существующие SCADA-
> системы (например, TraceMode), а так же про OPC, ModBus
> и иже с ними.
Почему Велосипед? Я же не делаю систему управления каким-либо производственным процессом...
> > Поток уничтожается в деструкторе класса, который вызывается
>
> > когда программу закрывают
>
>
> Какого класса ?
> Где он объявлен и где создан его экземпляр ?
> Где вызывается деструктор экземпляра ?
>
> Откуда хост-приложение знает про какой-то существующий в
> DLL доп.поток ?
Класс объявлен в длл
MCU_1b = class(TInterfacedObject,......,......)
функции вызываемые из главной программы:
function MCU_1b.DoCmd1(...);
begin
end;
function MCU_1b.DoCmd2(...);
begin
end;
......
destructor MCU_1b.destroy;
begin
!
end;
> > WaitForSingleObject(ThreadHandle....)
> > TerminateThread(ThreadHandle)
>
>
> Ерунда какая-то ..
> Зачем тут TerminateThread ?
>
> Если все это делается при финализации dll, то код неработоспособен
> - вызов ф-ции WaitForSingleObject лишен смысла, ибо она
> никогда не дождется завершения выполнения поточной функции.
>
В деструкторе класса (не при финализации длл) terminated:=true; жду завершения потока некоторое время, если не дожидаюсь - то убиваю поток.
Сергей М. (2006-12-08 09:04:00) [8]
> Mixal__ (07.12.06 14:07) [36]
> Контроль - это опрос разных датчиков.
>
> Вроде того: запустили вы программу - у вас в разных окошках
> меняются всякие значения - ну допустим температура, давление,
> скорость воздуха, уровень воды в баке итп. А нажали кнопку
> - у вас хопа и включился насос итп.
Понятно.
Велосипед, значит, изобретаем)
Почитай что-нть научно-популярное про ужесуществующие SCADA-системы (например, TraceMode), а так же про OPC, ModBus и иже с ними.
> Поток уничтожается в деструкторе класса, который вызывается
> когда программу закрывают
Какого класса ?
Где он объявлен и где создан его экземпляр ?
Где вызывается деструктор экземпляра ?
Откуда хост-приложение знает про какой-то существующий в DLL доп.поток ?
> WaitForSingleObject(ThreadHandle....)
> TerminateThread(ThreadHandle)
Ерунда какая-то ..
Зачем тут TerminateThread ?
Если все это делается при финализации dll, то код неработоспособен - вызов ф-ции WaitForSingleObject лишен смысла, ибо она никогдане дождется завершения выполнения поточной функции.
Leonid Troyanovsky (2006-12-07 14:36:00) [9]
> Mixal__ (07.12.06 14:07) [36]
> Поток уничтожается в деструкторе класса, который вызывается
> когда программу закрывают, примерно так:
Т.е., есть подозрения, что он не уничтожится при завершении процесса?
И, вообще, не очень понятно, почему для включения насосов
потребовалась dll.
Остается лишь надеяться, что все эти "плагины" не для автоматизации
опасных производств.
--
Regards, LVT.
Mixal__ (2006-12-07 14:07:00) [10]2Сергей М. ©
Контроль - это опрос разных датчиков.
Вроде того: запустили вы программу - у вас в разных окошках меняются всякие значения - ну допустим температура, давление, скорость воздуха, уровень воды в баке итп. А нажали кнопку - у вас хопа и включился насос итп.
Поток уничтожается в деструкторе класса, который вызывается когда программу закрывают, примерно так:
....
terminated := true;
PulseEvent(eventHandle)
WaitForSingleObject(ThreadHandle....)
TerminateThread(ThreadHandle)
CloseHandle(ThreadHandle)
CloseHandle(eventHandle)
.....
Сергей М. (2006-12-07 08:21:00) [11]
> Mixal__ (06.12.06 13:33) [29]
> Поток нужен в любом случае т.к. необходим постоянный контроль
> устройства
Контроль на предмет чего?
Кстати вопрос на засыпку - при инициализации ты создаешь тред, а где, когда и как он у тебя уничтожается ?
Anatoly Podgoretsky (2006-12-06 21:26:00) [12]> Kolan (06.12.2006 17:19:33) [33]
Поводок в данном случае - время реакции, у MS Windows оно 10 мс
Раньше такое время и не снилось.
Ни одна многозадачная системе не является системой реального времени, она только более или менее похожа на нее. Стандартная Виндоус не лучшее решение для построения систем реального времени, для этого больше подходят Embeded решения, начиная от НТ и до ХР как минимум.
Там можешь формировать ядро с точностью до функции.
Kolan (2006-12-06 17:19:00) [13]> поводка
Даже более того я незнаю что есть "поводок".
Kolan (2006-12-06 17:18:00) [14]> Назови систему подлинного реального времени, только не с
> разной длиной поводка, а именно подлинную.
Незнаю. Знаю что Windows не из их числа.
> Тебя обманули, ты пока новенькие и еще не знаешь кого не
> следует слушать.
А это в мой огород камень. Тады пользуй Sleep для ожидания, пользуй.
> Как узнать, занято в данный момент устройство выполнением
> предыдущей посланной команды?
Оно само должно об этом уведомить...
Anatoly Podgoretsky (2006-12-06 14:18:00) [15]> Mixal__ (06.12.2006 12:46:25) [25]
> И чем заменить sleep раз он такой глючный...
Тебя обманули, ты пока новенькие и еще не знаешь кого не следует слушать.
Anatoly Podgoretsky (2006-12-06 14:16:00) [16]> Kolan (06.12.2006 10:40:12) [12]
Назови систему подлинного реального времени, только не с разной длиной поводка, а именно подлинную.
Mixal__ (2006-12-06 13:33:00) [17]2Сергей М. ©
Поток нужен в любом случае т.к. необходим постоянный контроль устройства, с периодом не менее 1сек, а функции из длл вызываются только при необходимости, могут и вообще не вызываться в течении продолжительного времени.
А так как у меня не используются спец. линии для того-чтобы понять - готово устройство или нет, как например у модема, связь идёт только по линиям tx и rx, то ждать надо полюбому.
И всё-же чем заменить Sleep? - смотреть системный таймер миллисекунд и считать? Насколько я помню есть ф-я гдето в кернеле timeGetTime-возвращает сколько прошло мс после запуска винды- может воспользоваться ей?
Сергей М. (2006-12-06 13:06:00) [18]
> Mixal__ (06.12.06 12:46) [25]
Да и доп.поток твой при таком раскладе вовсе не нужен - при каждом вызове какой-либо ф-ции из dll сначала ожидается готовность устройства и после этого осуществляется инф.обмен с ним. Это в предположении, что вызовы этих ф-ций осуществляются последовательно.
Mixal__ (2006-12-06 13:06:00) [19]2C
Устройство выдаёт ответ после полной обработки команды, но дело в том, что устройство занимается не только обработкой запросов с ПК... Если придёт команда во время того, когда контроллер чемто занят - это не страшно - команда попадёт в буфер, но её обработка начнётся только тогда, когда пройдёт полный цикл работы устройства.
Поэтому чтобы не "завалить" устройство запросами надо немного подождать.
Сергей М. (2006-12-06 13:03:00) [20]
> несовсем понятно, почему обязательно использовать механизм,
> при котором работа с портом будет происходить из одного
> потока
Потому что децентрализация логики плоха сама по себе.