Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.10.08;
Скачать: [xml.tar.bz2];

Вниз

Потоки.. не в зуб ногой   Найти похожие ветки 

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.067 c
15-1158468615
Чапаев
2006-09-17 08:50
2006.10.08
Как узнать путь к shell application?


1-1156600280
nali
2006-08-26 17:51
2006.10.08
Мерцания при прорисовке ячеек грида


2-1158821345
Dima K
2006-09-21 10:49
2006.10.08
Handle чужего окна


1-1156409591
DelphiLexx
2006-08-24 12:53
2006.10.08
FormStyle=fsMdiChild и FormStyle=fsNormal отрисовыв. по разному?


15-1158435160
Ajax
2006-09-16 23:32
2006.10.08
Включение компьютера без видеокарты





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский