информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Портрет посетителяВсе любят медГде водятся OGRы
BugTraq.Ru
Русский BugTraq
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Модель надежности отказоустойчивой... 
 Некоторые пароли от G Suite хранились... 
 Microsoft выпустила Windows Sandbox 
 Microsoft выпустила исправление... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Как корректно остановить поток, который ушел в АПИ-шную ф-цию и не вернулся? 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
<"чистая" ссылка>
А PCI-COM не подойдет? Например, такое:
КОНТРОЛЛЕР CONTROLLER ST-LAB, PCI, I-142, 2 EXT (COM9M) - 499р.
http://www.st-lab.ru/catalog/kontrolleri/controller-st-lab-pci-i-142-2-ext-com9m-ret.html
http://www.sunrichtech.com.hk/ProductShow.aspx?Mid=1&pid=27 - контроллер на чипе Moshcip 9835 - заявлена поддержка 16C550UART , EIA RS-232-C, CCITT V.24, но насколько она там честно реализована... Попробуй потерзать саппорт st-lab.ru - мож подскажут.
Так это - PCI-COM. А к линии ноут прикручен. 20.06.14 02:00  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
1ю половину задачи вроде решил - RTS управляется независимо от приема/передачи.
Победил. Имеющийся конвертор RTS поддерживает. 20.06.14 15:00  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
Юзал ::EscapeCommFunction(hSerial, CLRRTS) безо всяких дополнительных параметровв DCB. RTS просто включается/выключается по команде. Передача/прием на него не влияют.
CancelSynchronousIo либо использовать асинхронный ввод и CancelIo 28.04.14 21:02  
Автор: dl <Dmitry Leonov>
<"чистая" ссылка>
CancelSynchronousIo, это Vista+, а у меня панель под ХР на роботе. 29.04.14 05:30  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
Похоже - попал, если в Висте специальную ф-цию для этого завели...

А с асинхронным вводом я рехнусь с семафорами и получится хрень, в работоспособности которой никогда на 100% уверенным быть нельзя.
а какие проблемы с асинхронным вводом? 29.04.14 10:56  
Автор: dl <Dmitry Leonov>
<"чистая" ссылка>
Сразу после него втыкается WaitForMultipleObjects, ждущая два события - отмены по кнопке и завершения из OVERLAPPED.
Вот тут я до конца не соображаю! 29.04.14 17:28  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
> Сразу после него втыкается 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>
<"чистая" ссылка>
Ну, да! А как онтада семафоры проверяет? Через аппаратный контроллер прерываний? 30.04.14 15:00  
Автор: Zef <Alloo Zef> Статус: Elderman
Отредактировано 30.04.14 15:24  Количество правок: 1
<"чистая" ссылка>
Тот же бесконечный цикл, только в ядре.

А мож, и правда, все сходится к 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 уменя есть.

Но вообщетакой подход типичен для АСУ РВ.
какая разница, мульти, сингл 01.05.14 18:25  
Автор: dl <Dmitry Leonov>
<"чистая" ссылка>
Размораживается все равно одна точка, в которой был заморожен поток. С каждым объектом связан список ждущих его потоков. Если при освобождении объекта видно, что первый в очереди ждущий его поток вызыван с WaitForSingleObject либо WaitForMultipleObject с bWaitAll=false, он сразу размораживается. Если нет, проверяются другие объекты.

Внутри ядра есть и спин-блокировки, ну а пользовательский код синхронизируется в основном так. Подробнее можно посмотреть, например, тут: http://wm-help.net/lib/b/book/902402587/3 - в районе раздела "Структуры данных".
Выручайте, не бычит! 02.05.14 17:34  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
Делаю примерно так:
DCB dcbSerialParams = {0};
char Code[20], Code2[20];
HANDLE hSerial, hEvent[2];
OVERLAPPED m_OvrLapped;
DWORD dwEvent = EV_RXCHAR;

void CBarcodeDlg::OnAutoBtn()
{
if ((endNum >= startNum)&&!FromFile){return;}
::EnableWindow(hAutoBtn, false);
hEvent[0] = ::CreateEvent(NULL, true, false, NULL);
hEvent[1] = ::CreateEvent(NULL, false, false, NULL);
m_OvrLapped.hEvent = hEvent[1];
m_OvrLapped.Offset = 0;
m_OvrLapped.OffsetHigh = 0;
_beginthread( Thread, 0, NULL );
}

void Thread( void* pParams )
{
while(true)
{
//Готовим содержимое массива Data

BOOL iRet = WriteFile (hSerial, Data,20,&iSize,NULL);//Отправляем
ReadFile(hSerial, (char*)&sReceived, 1, &iSize, &m_OvrLapped); // Ждем подтверждение
dwEvent = WaitForMultipleObjects(2, hEvent, false, INFINITE);
if(dwEvent == WAIT_OBJECT_0){goto err;}
if (iSize == 0|sReceived != 0x06) {goto err;}
}
err:CancelIo(hSerial);
_endthread();

}

void CBarcodeDlg::OnStopBtn()
{
SetEvent(hEvent[0]);
this->GetDlgItem(IDC_BUTTON4)->EnableWindow(false);
}

WaitForMultipleObjects по кнопке не срабатывет. По чтению - не знаю, дома нечем проверить.
2я порция гимороя: 07.05.14 11:10  
Автор: Zef <Alloo Zef> Статус: Elderman
Отредактировано 07.05.14 11:12  Количество правок: 1
<"чистая" ссылка>
Делаю примерно так:
DCB dcbSerialParams = {0};
char Code[20], Code2[20];
HANDLE hSerial, hEvent[2];
OVERLAPPED m_OvrLapped;
DWORD dwEvent = EV_RXCHAR;

hSerial = ::CreateFile(sPortName,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL||FILE_FLAG_OVERLAPPED,0);

void CBarcodeDlg::OnAutoBtn()
{
if ((endNum >= startNum)&&!FromFile){return;}
::EnableWindow(hAutoBtn, false);
hEvent[0] = ::CreateEvent(NULL, true, false, NULL);
hEvent[1] = ::CreateEvent(NULL, false, false, NULL);
m_OvrLapped.hEvent = hEvent[1];
m_OvrLapped.Offset = 0;
m_OvrLapped.OffsetHigh = 0;
_beginthread( Thread, 0, NULL );
}

void Thread( void* pParams )
{
while(true)
{

//Готовим содержимое массива Data

BOOL iRet = WriteFile (hSerial,
Data,20,&iSize,NULL);//Отправляем
ReadFile(hSerial, (char*)&sReceived, 1, &iSize, &m_OvrLapped); // Ждем подтверждение
dwEvent = WaitForMultipleObjects(2, hEvent, false, INFINITE);
if(dwEvent == WAIT_OBJECT_0){goto err;}
if (iSize == 0|sReceived != 0x06) {goto err;}
}
err:CancelIo(hSerial);
_endthread();
}

void CBarcodeDlg::OnStopBtn()
{
SetEvent(hEvent[0]);
this->GetDlgItem(IDC_BUTTON4)->EnableWindow(false);
}

Если не ставлю атрибут файла "нормал", то Рид выскакивает нихрена не прочитав, но по стопу все останавливается сразу.
Если ставлю "нормал", то читает правильно, но останавливается только если чтение завершится. Вся беда состоит в том, что останавливать-то надо именно если исполнительное у-во не отвечает!
1. нормал поглощается другими атрибутами. 2. waitformultipleobjects(... infinite); в твоём контексте не имеет смысла. тебе надо поставить конкретный таймаут ожидания после которого проверяй результат чтения. при ошибке считай "зависло". 07.05.14 13:03  
Автор: kstati <Евгений Борисов> Статус: Elderman
Отредактировано 07.05.14 13:05  Количество правок: 2
<"чистая" ссылка>
FILE_ATTRIBUTE_NORMAL
128 (0x80)
The file does not have other attributes set. This attribute is valid only if used alone.

All other file attributes override FILE_ATTRIBUTE_NORMAL
File_attribute_normal не имеет смысла в сочетании с другими флагами 07.05.14 11:43  
Автор: dl <Dmitry Leonov>
<"чистая" ссылка>
ReadFile при overlapped, ествественно, выходит сразу, после чего нужно ждать на WaitFor окончания операции чтения.
1  |  2  |  3 >>  »  






Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2019 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach