Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.52 MB
Время: 0.081 c
1-1156666261
AlexeyT
2006-08-27 12:11
2006.10.08
Что за контрол отвечает за MCIWndClass?


2-1158914654
jjj
2006-09-22 12:44
2006.10.08
Вопрос по TBitBtn


15-1158242180
ceval
2006-09-14 17:56
2006.10.08
функции - информацию о процессоре и загрузки


1-1155810465
GrBob
2006-08-17 14:27
2006.10.08
Variant и Int64


2-1158753160
Rubey
2006-09-20 15:52
2006.10.08
Вывод в ячейку StringGrid-a