Проблема, видимо, вообще втом, что ReadFile применительно к СОМ-поту может быть только синхронным. До поступления заказанного количества байт он лочится где-тв ядре и прервать его евентами юзермода не возможно. Цепочка:
Как корректно остановить поток, который ушел в АПИ-шную ф-цию и не вернулся?28.04.14 15:10 [HandleX] Автор: Zef <Alloo Zef> Статус: Elderman Отредактировано 28.04.14 15:20 Количество правок: 1
Проблема такая: прога отправляет на девайс через СОМ-порт данные и ждет ответа, затем - снова, пока все данные не кончатся или не будет нажат СТОП. В ней 2 потока - ГУИ и обмен с портом. Беда в том, что когда девайс глючит и не отвечает, поток не выходит из ReadFile и не может проверить семафор от кнопки СТОП, по которому он завершается. Из-за этого перезапустить передачу невозможно, а прога с висящим потоком закрывается тока через 3 кнопки.
А кто знает, USB/Com конверторы DTR и RTS управлять умеют?19.06.14 05:07 Автор: Zef <Alloo Zef> Статус: Elderman
И если не все, то какие - да? Задача хитрозадая: управляемый девайс (принтер-маркировщик) не умеет останавливаться при прерывании связи. Т.е. он шлепает этикетку по сигналу с поточной линии. Если я успел загрузить данные с компа - он печатает их. Если нет - последние загруженные. Мне надо, чтобы при обрыве связи печать прекращалась. Не нашел варианта лучше использования DTR или RTS в качестве сигнала разрешения печати. Подляна в том, что принтеров - 2, а найти комп с двумями Com-портами - не реально. Мультипортовые платы искать, то же, не айс, а USB везде полно.
Подозреваю, что это может сказать только производитель19.06.14 12:40 Автор: JINN <Sergey> Статус: Elderman
Юзал ::EscapeCommFunction(hSerial, CLRRTS) безо всяких дополнительных параметровв DCB. RTS просто включается/выключается по команде. Передача/прием на него не влияют.
CancelSynchronousIo либо использовать асинхронный ввод и CancelIo28.04.14 21:02 Автор: dl <Dmitry Leonov>
> Сразу после него втыкается WaitForMultipleObjects, ждущая > два события - отмены по кнопке и завершения из OVERLAPPED. Значит, вывод - синхронный, а ожидание ответа - асинхронное? А они очередность не попутают? Не получится, что запоздавший ответ на предыдущий запрос будет воспринят, как на текущий? А если и вывод и ввод сделать асинхронными, они не попутают очередность? Или их между собой то же надо семафорить? И что произойдет в случае одновременности запроса и ответа?
Я подобной хренью тяжко страдал при написании своей модификации "Филемона" и, похоже, так все "клинчи" и не разрулил, сколько не бился. До сих пор уменя от этого весьма тягостные воспоминания.
все асинхронное29.04.14 17:37 Автор: dl <Dmitry Leonov>
WaitFor для того и нужен, чтобы гарантированно дождаться завершения асинхронной операции. Асинхронный ReadFile/WriteFile и следующий за ним WaitFor с точки зрения логики программы почти не отличается от привычного синхронного ReadFile/WriteFile. За исключением того, что в промежуток между ними можно воткнуть какие-то еще действия, плюс сказать WaitFor, что он может ждать не только завершения операции чтения, но и сигнала от интерфейса. И если пришел сигнал от интерфейса, то убить незаконченную операцию чтения через CancelIo, который есть и в XP.
Фу, въехал! Про WaitForMultipleObjects не сообразил.30.04.14 07:32 Автор: Zef <Alloo Zef> Статус: Elderman
Просто, очень мутные у Мелкомягких описания и потому трудно понять, для чего это.
Фактически WaitForMultipleObjects - бесконечный цикл ожидания установки 2х семафоров, в моем случае - окончания ввода или нажатия СТОП. А кнопка СТОП не булевскую переменную должна устанавливать, а бъект "стоп".
да, только он лучше бесконечного цикла, поскольку не тратит процессорное время30.04.14 12:23 Автор: dl <Dmitry Leonov>
А мож, и правда, все сходится к INTn? Синхронизируемый поток передает системе список калбэков на себя и отдает управление. Система вычеркивает его из очереди выделения квантов времени. Синхронизирующий поток вызывает INT, ядро по прерыванию передает управление по калбэку и снова вносит поток в очередь планировщика?
зачем список колбэков?01.05.14 03:32 Автор: dl <Dmitry Leonov> Отредактировано 01.05.14 03:36 Количество правок: 1
Планировщик же в курсе, какие потоки ждут какие объекты. Пока нужный объект не освободится, поток просто удаляется из карусели. И возвращается, когда вызвалась какая-нибудь функция, освободившая объект. Тогда берется первый поток из очереди ждущих освобождения этого объекта и размораживается.
С точки зрения системы момент освобождения объекта не является неопределенным, его не нужно ждать в цикле.
А Мульти-то как сделать?01.05.14 05:29 Автор: Zef <Alloo Zef> Статус: Elderman
Если Сингл - переходим на следующую команду за Вайтом, а если Мульти - по разным адресам в зависимости от того, какое событие. А кстати, оно и правда так сделано? (Звиняюсь, лень исходники смотреть, хота и Реактос и 2000 уменя есть.
Размораживается все равно одна точка, в которой был заморожен поток. С каждым объектом связан список ждущих его потоков. Если при освобождении объекта видно, что первый в очереди ждущий его поток вызыван с WaitForSingleObject либо WaitForMultipleObject с bWaitAll=false, он сразу размораживается. Если нет, проверяются другие объекты.
Внутри ядра есть и спин-блокировки, ну а пользовательский код синхронизируется в основном так. Подробнее можно посмотреть, например, тут: http://wm-help.net/lib/b/book/902402587/3 - в районе раздела "Структуры данных".
Выручайте, не бычит!02.05.14 17:34 Автор: Zef <Alloo Zef> Статус: Elderman
Если не ставлю атрибут файла "нормал", то Рид выскакивает нихрена не прочитав, но по стопу все останавливается сразу.
Если ставлю "нормал", то читает правильно, но останавливается только если чтение завершится. Вся беда состоит в том, что останавливать-то надо именно если исполнительное у-во не отвечает!
1. нормал поглощается другими атрибутами. 2. waitformultipleobjects(... infinite); в твоём контексте не имеет смысла. тебе надо поставить конкретный таймаут ожидания после которого проверяй результат чтения. при ошибке считай "зависло".07.05.14 13:03 Автор: kstati <Евгений Борисов> Статус: Elderman Отредактировано 07.05.14 13:05 Количество правок: 2