Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Необходимо ли операции с СОМ портом, выполняемые из различных.. [D7, WinXP]


Balkon ©   (2006-06-08 12:45:00) 

потоков, выносить в критические секции.
Спасибо за внимание.


tesseract   (2006-06-12 09:27:00) [1]


> Ihor Osov'yak ©   (11.06.06 02:01) [18]


Кто знает, вдруг больше потоков придёться создавать?


Ihor Osov'yak   (2006-06-11 02:01:00) [2]

2 tesseract,

вспомнил одну байку, из глубокого детсва...

- слуш, зачем ты два талона компостируешь?
- а вдруг один потеряю, а тут контроль?
- а если оба потеряешь?
- ну, на этот случай у меня проездной..


tesseract   (2006-06-10 09:30:00) [3]


>  хотя они почти все многопоточные, я ни разу не использовал
> критических секций. Не возникало необходимости.

я просто для перестраховки их использовал. Вдруг чего, не так.


Ihor Osov'yak   (2006-06-09 18:00:00) [4]

Зависит от архитектуры приложения и способа работы с портом.  Для примера, в своих поделках, имеющих отношение к ком-портам,  хотя они почти все многопоточные, я ни разу не использовал критических секций. Не возникало необходимости.


Balkon   (2006-06-09 13:49:00) [5]

Спасибо большое.


Сергей М.   (2006-06-09 12:05:00) [6]


> Нет ли в ней чего зазорного?


Есть.

Отсутствует анализ результатов, возвращаемых ф-циями Read/WriteFile, WaitCommEvent


Balkon   (2006-06-09 11:03:00) [7]

Привет опять. Спасибо.
Переписал используя один поток, который при создании своем открывает порт и наоборот соотсно.

При создании потока в него передается команда, которую он должен плюнуть в девайс и дождаться либо правильного ответа, либо достижения определенного числа повторов команды без получения правильного ответа.

Ниже приведена реализация. Нет ли в ней чего зазорного?


procedure TAKRThread.Execute;
Var
   CurrentState : TComStat;
   AvaibleBytes, ErrCode, RealRead : Cardinal;
   ReadOL : TOverLapped;
   Signaled, Mask : DWORD;
   BytesTrans : DWORD;

   TmpPackage: TReadPackage;
Begin
 if WriteAKRComand then
 Try
   FillChar(ReadOL, SizeOf(ReadOL), 0);
   ReadOL.hEvent:= CreateEvent(nil, True, True, nil);
   SetCommMask(FPortHandle, EV_RXCHAR);
   while (not Terminated)  do
   begin
     WaitCommEvent(FPortHandle, Mask, @ReadOL);
     Signaled:= WaitForSingleObject(ReadOL.hEvent, 1000);
     if (Signaled  = WAIT_OBJECT_0)and
        GetOverlappedResult(FPortHandle, ReadOL, BytesTrans, False) then
     begin
        If (Mask and EV_RXCHAR) <> 0 then
        begin
         ClearCommError(FPortHandle, ErrCode, @CurrentState);
         AvaibleBytes:= CurrentState.cbInQue;
         if (AvaibleBytes > 0) and
           ReadFile(FPortHandle, TmpPackage, AvaibleBytes, RealRead, @ReadOL) then
             CheckBytes(TmpPackage,AvaibleBytes);
       End;
     end
     else
       RepeatAKRComand;
   End;
 Finally
   CloseHandle(ReadOL.hEvent);
   SetCommMask(FPortHandle, 0);
 End;
End;

function TAKRThread.WriteAKRComand: boolean;
var
 Signaled, RealWrite, BytesTrans : Cardinal;
 WriteOL : TOverLapped;
begin
 FillChar(WriteOL, SizeOf(WriteOL), 0);
 WriteOL.hEvent:= CreateEvent(nil, True, True, nil);
 Try
   WriteFile(FPortHandle, FComandPackage, SizeOf(FComandPackage), RealWrite, @WriteOL);
   Signaled:= WaitForSingleObject(WriteOL.hEvent, INFINITE);
   Result := (Signaled = WAIT_OBJECT_0) and
     GetOverlappedResult(FPortHandle, WriteOL, BytesTrans, False);
 Finally
   CloseHandle(WriteOL.hEvent);
 End;
end;


Процедура CheckBytes(TmpPackage,AvaibleBytes) проверяет после каждой порции прилетевший байт набрался ли ответ и анализирует его корректность.


Сергей М.   (2006-06-08 15:14:00) [8]


> на посылку команды некому девайсу получить от него ответ


Ну и зачем при этом, спрашивается, два потока ?

Очевидно же - одного достаточно ...

function Get(Request: TSomeRequestType): TSomeResultType;

В теле подобной ф-ции, исполняемой контексте некоего транспортного потока, дивайсу посылаются данные в формате TSomeRequestTypeт и ожидается/возвращается от дивайса ответ в формате TSomeResultType.

Ы ?


Balkon   (2006-06-08 14:57:00) [9]

Прошу прощения,
ухожу из сети.

Завтра с удовольствием почитаю совтеы и ответы ежели таковые будут.
Спасибо. Берегите сябя. ;)


Balkon   (2006-06-08 14:46:00) [10]

Сделано все для того, чтобы на посылку команды некому девайсу получить от него ответ, либо по таймауту повторить команду.

процедура пишушего потока:

 FillChar(WriteOL, SizeOf(WriteOL), 0);
 WriteOL.hEvent:= CreateEvent(nil, True, True, nil);
 FinpAKRThread := TinpAKRThread.Create(false,FOwner,FPortHandle,FComandPackage,FThreadAnswer); //Создаю читающий поток
 Try
   WriteFile(FPortHandle, FComandPackage, SizeOf(FComandPackage), RealWrite, @WriteOL);
   Signaled:= WaitForSingleObject(WriteOL.hEvent, INFINITE);
   if (Signaled = WAIT_OBJECT_0) and
     (GetOverlappedResult(FPortHandle, WriteOL, BytesTrans, False)) then
   begin
     FinpAKRThread.WaitFor;


Обмениваются данными потоки в критической секции.


Сергей М.   (2006-06-08 14:38:00) [11]


> Вот кусок процедуры читающего потока:


Давай уж тогда и кусок пишущего приводи ..


Balkon   (2006-06-08 14:35:00) [12]

Спасибо опять...
Не знаю зачем, но делаю отдельные потоки пишущий и читающий.
Вот кусок процедуры читающего потока:

FillChar(ReadOL, SizeOf(ReadOL), 0);
   ReadOL.hEvent:= CreateEvent(nil, True, True, nil);
   SetCommMask(FPortHandle, EV_RXCHAR);
   while (not Terminated)  do
   begin
     WaitCommEvent(FPortHandle, Mask, @ReadOL);
     Signaled:= WaitForSingleObject(ReadOL.hEvent, 1000);
     if (Signaled  = WAIT_OBJECT_0)and
       GetOverlappedResult(FPortHandle, ReadOL, BytesTrans, False) then
     begin
       If (Mask and EV_RXCHAR) <> 0 then
       begin
           ...


И будте добры поясните, почему транспортный поток должен быть один и тот же? Вроде бы в различных компонентах и в книге Агурова чтение из порта выносится в отдельный поток. Или я что-то неправильно понял?


tesseract   (2006-06-08 14:21:00) [13]


> На то существует overlapped - режим и completion routines
> - режим ..

Лучше использовать маску EV_RXCHAR,  тогда порт реально сообщит, что что-то пришло. а overlapped просто помогает дожаться нужного кол-ва данных.


Сергей М.   (2006-06-08 14:19:00) [14]


> Как же тогда реализовывать, скажем, опрос порта, в цыкле?


А нечего его опрашивать !
Он сам сообщит о событиях, в нем произошедших ..
На то существует overlapped - режим и completion routines - режим ..
Без цикла здесь и вправду не обойтись, но цикл этот занимается не только и не столько неким "опросом", сколько ожиданием неких событий в неких подсистемах ввода-вывода, в частности - подсистеме файлововго ввода-вывода, к коей принадлежит и ввод-вывод подсистемы последовательных коммуникаций.

См. WinAPI Wait-функции.


Сергей М.   (2006-06-08 14:13:00) [15]


> :) странные мне вещи вы говорите.


Да нет, вовсе не странные это вещи...

Транспортныйпоток должен быть один и тот же, его ф-ция - прием/передача неких данных... Подготовка/обработка же (передаваемых/принимаемых) данных должна в этом случае быть возложена на один или более других потоков.


Balkon   (2006-06-08 14:03:00) [16]

:) странные мне вещи вы говорите.

Как же тогда реализовывать, скажем, опрос порта, в цыкле?
Я так понимаю что "спящий" до появления новых данных отдельный
поток опроса порта- это вполне оправданное решение.


tesseract   (2006-06-08 13:52:00) [17]


> Спасибо.А если порт один, а потоков несколько - пишущий,
>  читающий и меняющий настройки (интерфейсный)?

Это уже критические извращения, не делай так никогда.


Balkon   (2006-06-08 13:41:00) [18]

Спасибо.
А если порт один, а потоков несколько - пишущий, читающий и меняющий настройки (интерфейсный)?


tesseract   (2006-06-08 13:08:00) [19]

Если один поток - один порт, то в секции надо выносить только передачу данных в главный поток.


Наверх

Титульная страница Поиск, карта сайта Написать письмо