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

Вниз

Необходимо ли операции с СОМ портом, выполняемые из различных..   Найти похожие ветки 

 
Balkon   (2006-06-08 12:45) [0]

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


 
tesseract ©   (2006-06-08 13:08) [1]

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


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

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


 
tesseract ©   (2006-06-08 13:52) [3]


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

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


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

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

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


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


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


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

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


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


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


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

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


 
tesseract ©   (2006-06-08 14:21) [7]


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

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


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

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

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
           ...


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


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


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


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


 
Balkon   (2006-06-08 14:46) [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;


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


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

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

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


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


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


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

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

function Get(Request: TSomeRequestType): TSomeResultType;

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

Ы ?


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

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

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

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


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-09 12:05) [14]


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


Есть.

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


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

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


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

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


 
tesseract ©   (2006-06-10 09:30) [17]


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

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


 
Ihor Osov'yak ©   (2006-06-11 02:01) [18]

2 tesseract,

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

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


 
tesseract ©   (2006-06-12 09:27) [19]


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


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



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2006.10.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.044 c
3-1155735139
danja12
2006-08-16 17:32
2006.10.22
Как сжать dbf с помощью TADOTable?


1-1158231300
простак
2006-09-14 14:55
2006.10.22
связность графа....


15-1159535957
sergey888
2006-09-29 17:19
2006.10.22
Микрософт вплотную занялась играми


2-1159817219
Juri
2006-10-02 23:26
2006.10.22
Печать.


3-1155875302
Rentgen
2006-08-18 08:28
2006.10.22
Kак пересортировать таблицу после изменения поля в самой таблице?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский