Текущий архив: 2006.10.08;
Скачать: CL | DM;
ВнизПотоки.. не в зуб ногой Найти похожие ветки
← →
POP (2006-09-09 18:16) [0]Я написал программу которая посылает команды в модем и принимает ответ выводя его на экран. Порт открываю в синхроне, все работает.
Чтобы прога не висла в ожидании ответа (если модем не отвечает), нужно фунцию ожидания (WaitCommEvent) и чтения из порта сделать в отдельном потоке. Вот тут я натыкаюсь на проблемы.
В асинхрон пока не лезу, надо разобраться сначала в более легком.
По потоки читал в Библии Delphi Фленова. Пока создал новый поток в программе пустой ((New - Thread Object)
Вопросы у меня возникли такие:
Открытие и конфигурация порта происходит в главном модуле, так вот как общаться с новым потоком, например передавать ему handle открытого порта , маску (SetCommMask) ожидаемого события и другие переменные?
И как забирать прочитанные данные из созданного потока, которые функция ReadFile хранит в своем буфере после прочтения?
Я так понял у каждого потока должны быть свои переменные, которые не должны пересекаться.
Про синхронизацию читал у Фленова , но там все очень кратко описано. Непонятно с переменными.
Подскажите плиз кто знает.
← →
Ketmar © (2006-09-09 18:39) [1]сначала пообещай больше не читать ни Флёнова, ни Архангельского. потом, может, и помогут.
← →
Юрий Зотов © (2006-09-09 19:29) [2]
type
TMyThread = class(TThread);
protected
procedure Execute; override;
public
PortHandle: THandle;
... // Поля для хранения других входных данных.
Buffer: ... // Буфер с прочитанными данными
end;
procedure TMyThread.Execute;
begin
... // Заполняем Buffer
end;
> как общаться с новым потоком, например передавать ему...
procedure TForm1.Button1Click(Sender: TObject);
begin
with TMyThread.Create(True) do // Создали замороженный поток.
try
PortHandle := ...; // Устанавливаем все входные данные.
FreeOnTerminate := True; // Объект самоуничтожится.
OnTerminate := ThreadTerminated; // Сработает при выходе из Execute.
Resume; // Запустили поток на выполнение.
except
Free;
raise
end
end;
...и как забирать прочитанные данные
procedure TForm1.ThreadTerminated(Sender: TObject);
begin
with TMyThread(Sender) do
begin
... // Забираем прочитанные данные из Buffer
end
end;
> Я так понял, у каждого потока должны быть свои переменные,
> которые не должны пересекаться
Правильно поняли. Такие переменные называются полями объекта. Объявляются они в описаниии класса объекта, а область видимости каждого поля определяется тем разделом, в котором она объявлена. Каждый созданный при выполнении программы экземпляр класса будет иметь свой собственный набор этих полей. И очень жаль, что в библии не описаны даже эти базовые понятия объектной модели. Потому что хотя бы с ее базовыми понятиями должен быть знаком каждый, кто берется писать программы на Delphi. Это азы, букварь, а писать без знания букваря - невозможно.
> читал у Фленова
Не то читаете. Читайте Тейксейру с Пачеко.
← →
Mike Petrichenko (2006-09-10 01:15) [3]
> Чтобы прога не висла в ожидании ответа (если модем не отвечает),
> нужно фунцию ожидания (WaitCommEvent) и чтения из порта
> сделать в отдельном потоке. Вот тут я натыкаюсь на проблемы.
>
А прежде чтим MSDN.
Если используется не Overlapped IO, то возможен DeadLock на таком фале (COM порте).
P.S. Кто не верит пришлю готовой пример с DeadLock так как на эти грабли наступил. Пришлось перечитывать Маркса.
← →
Германн © (2006-09-10 01:20) [4]
> Mike Petrichenko (10.09.06 01:15) [3]
>
>
> > Чтобы прога не висла в ожидании ответа (если модем не
> отвечает),
> > нужно фунцию ожидания (WaitCommEvent) и чтения из порта
> > сделать в отдельном потоке. Вот тут я натыкаюсь на проблемы.
>
> >
>
> А прежде чтим MSDN.
> Если используется не Overlapped IO, то возможен DeadLock
> на таком фале (COM порте).
>
> P.S. Кто не верит пришлю готовой пример с DeadLock так как
> на эти грабли наступил. Пришлось перечитывать Маркса.
Я верю. А пример пришли, пожалуйста. Мыло в анкете. Подобные вещи меня весьма интересуют по ряду причин.
← →
POP (2006-09-10 01:43) [5]
> А прежде чтим MSDN.
> Если используется не Overlapped IO, то возможен DeadLock
> на таком фале (COM порте).
Ты имеешь ввиду зависон? Ну да, если модем не отвечает, то WaitCommEvent будет вечно ждать RXCHAR, хотя основной поток будет рабочий. Но я пока с синхроном разбираюсь.
> Правильно поняли. Такие переменные называются полями объекта.
> Объявляются они в описаниии класса объекта, а область видимости
> каждого поля определяется тем разделом, в котором она объявлена.
> Каждый созданный при выполнении программы экземпляр класса
> будет иметь свой собственный набор этих полей. И очень жаль,
> что в библии не описаны даже эти базовые понятия объектной
> модели. Потому что хотя бы с ее базовыми понятиями должен
> быть знаком каждый, кто берется писать программы на Delphi.
> Это азы, букварь, а писать без знания букваря - невозможно.
>
Большое спасибо, после ваших примеров я успешно создал поток с ожиданием и чтнием и тд.
Но вот есть одна загвоздка, код потока такой:
procedure TReadComThread.Execute;
begin
WaitCommEvent(PortHandle,PortMask,nil);
//Sleep(500);
ClearCommError(PortHandle, Err, @ComStat);
CountB:= ComStat.cbInQue;
ReadFile(PortHandle, d, CountB, BytesRead, nil);
Exit;
end;
------
Тут такое дело, если не юзать Sleep, то CountB всегда меньше чем BytesRead, то есть WaitCommEvent сигнализирует о RXChar , ClearCommError выдает то что успело передаться к этому моменту, но передача до сих пор идет и к моменту ReadFile все успевает передаться.
Я думаю это не есть хорошо юзать Sleep, может есть какой-то выход для синхрона?
И второй вопрос, можно ли как отследить (например при помощи WaitCommEvent) о том что пришел последний байт и можно начинать чтение? например наложением масок или по другому?
← →
Германн © (2006-09-10 02:13) [6]
> POP (10.09.06 01:43) [5]
...
> Тут такое дело, если не юзать Sleep, то CountB всегда меньше
> чем BytesRead, то есть WaitCommEvent сигнализирует о RXChar
> , ClearCommError выдает то что успело передаться к этому
> моменту, но передача до сих пор идет и к моменту ReadFile
> все успевает передаться.
Почитай в хэлпе про COMMTIMEOUTS
> И второй вопрос, можно ли как отследить (например при помощи
> WaitCommEvent) о том что пришел последний байт
А что есть "последний байт"?
← →
Германн © (2006-09-10 02:27) [7]
> Германн © (10.09.06 02:13) [6]
Боже мой! Что я делаю!?
Помогаю новичку идти "не тем путём"!
Наверно сказываются последствия "слишком частого общения" с Кетмаром за последнее время! :-(
← →
POP (2006-09-10 13:36) [8]
> Почитай в хэлпе про COMMTIMEOUTS
>
>
> > И второй вопрос, можно ли как отследить (например при
> помощи
> > WaitCommEvent) о том что пришел последний байт
>
> А что есть "последний байт"?
Про COMMTIMEOUTS я знаю и даже устанавливаю в своей программе, но ставлю "наугад" либо смониторенные с других програм, потому что либо ответ на экран выводиться, а в portmone "timeout", либо читается только часть ответа. Поэтому приходиться перебирать.
Вся проблема в том, что у меня можно выбирать скорость соединения в любом диапозоне, причем неизвестно сколько байт придет в ответ, отслеживать конец по конкретному симоволу тоже не подходит, тк его нет, просто приходит ответ на команду и все (это не только AT команды). Работаю по 3 проводам, RX, TX, GND.
Я читал про таймауты как их люди устанавливают, но они заранее знают протокол передачи и все данные порта, например работают с каким специфическим устиройством.
> Боже мой! Что я делаю!?
> Помогаю новичку идти "не тем путём"!
Ты имеешь ввиду нужно переходить на ассинхрон? Ты не мог бы подсказать алгоритмику действий с учетом того что я написал выше? Разберусь с ассинхроном, если в синхроне это не реализовать.
← →
Mike Petrichenko (2006-09-10 15:54) [9]
> Ты имеешь ввиду зависон? Ну да, если модем не отвечает,
> то WaitCommEvent будет вечно ждать RXCHAR, хотя основной
> поток будет рабочий. Но я пока с синхроном разбираюсь.
Я имею ввиду, что при попытке чтения из потока и одновременной записи из другого потака будет deadlock.
← →
Mike Petrichenko (2006-09-10 16:02) [10]
> Я верю. А пример пришли, пожалуйста. Мыло в анкете. Подобные
> вещи меня весьма интересуют по ряду причин.
Отправил мылом. Прошу учесть просьбу которая в письме :)
← →
POP (2006-09-16 23:35) [11]Люди, ну ответьте кто-нить, у меня уже крыша едет с этих режимов.
← →
XbI (2006-09-17 16:17) [12]почитайте Рихтера, очень хорошо описаны потоки и процессы...
← →
POP (2006-09-17 20:27) [13]
> почитайте Рихтера, очень хорошо описаны потоки и процессы.
> ..
Да я не об этом, я про свое последнее сообщние, про потоки я разобрался, теперь про COM порт надо.
← →
XbI (2006-09-17 20:38) [14]а вам приходят данные, вы структуру и размер данных знаете?
← →
POP (2006-09-17 21:07) [15]
> а вам приходят данные, вы структуру и размер данных знаете?
Я специально создал две темы по этому поводу:
http://delphimaster.net/view/2-1158511777/
и
http://forum.sources.ru/index.php?act=ST&f=11&t=154787
Подскажите если сильны в этом деле. У меня уже крыша едет с этого асинхрона, с синхроном легче, но там загвоздки свои.
Страницы: 1 вся ветка
Текущий архив: 2006.10.08;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.049 c