![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| F_W |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 3 Регистрация: 10.12.2004 Репутация: нет Всего: нет |
Написал прогу, которая принимает данные из одного сом порта, обрабатывает по формату и передает в другой порт. Но есть один касяк. Когда просто запускаешь её, то она работает как надо. Но нужно, чтобы прием и передача шли все время (т.е. нужно порт все время слушать). Если её циклишь, то вылезает виндозная ошибка, типа программа вызвала ошибку и будет закрыта. Почему такое может происходить???
|
|||
|
||||
| bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 4 Всего: 47 |
Код в студию!
Через оверлапед делаешь? |
|||
|
||||
| F_W |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 3 Регистрация: 10.12.2004 Репутация: нет Всего: нет |
int main(int argc, char* argv[])
{ DCB dcb; COMMTIMEOUTS ct; HANDLE port1; DWORD mask; DWORD bc; char buf1[100]; dcb.DCBlength=sizeof(DCB); BuildCommDCB("baud=9600 parity=N data=8 stop=1",&dcb); dcb.fNull=TRUE; ct.ReadIntervalTimeout=10; ct.ReadTotalTimeoutMultiplier=ct.ReadTotalTimeoutConstant=0; ct.WriteTotalTimeoutMultiplier=ct.WriteTotalTimeoutConstant=0; //-----------открываем порт сом1 и считываем port1=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); SetCommState(port1,&dcb); SetCommTimeouts(port1,&ct); PurgeComm(port1,PURGE_RXCLEAR); SetCommMask(port1,EV_RXCHAR); WaitCommEvent(port1,&mask,NULL); ReadFile(port1,&buf1,100,&bc,NULL); CloseHandle(port1); HANDLE port2; char *buf_out=buf1; char *buf_in; int k=0,i=0, n; char x1[10],x2[20],*px1,*px2; char *buffer,*p,*p1; // ----------------убираем пробелы buffer=buf1; p = strtok (buffer," "); p1 = strtok (NULL," "); //--------------------------убираем буквы strupr(p1); p4 = strchr (p1,'K'); *p4=NULL; strcat (p1,"00 "); //-----------------------------заменяем , на . px1 = &p1[0]; px2 = &x2[0]; n = strlen(p1)+1; while (k<n) { if (*(px1+k)!=',') { *(px2+i) = *(px1+k); i++; k++; } else { *(px2+i) = '.'; k++; i += 1; } } //------------------------------ считываем из файла DOS символ (80) char* path = "3.txt"; char buf[10]; char* data; FILE *file; file = fopen(path, "r"); fgets(buf, 30, file); data=buf; fclose(file); //----------------------------------------- соединяем в конечный результат strcat(data, x2); strcat(data, "B \r\n"); cout <<"Read to COM2: " << data; buf_out=data; // -----------------------------------------отправляем данные port2=CreateFile("COM2",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); if (port2=="INVALID_HANDLE_VALUE") {cout << "Can't Open Port"; else { SetCommState(port2,&dcb); SetCommTimeouts(port2,&ct); PurgeComm(port2,PURGE_TXCLEAR|PURGE_RXCLEAR); WriteFile(port2,buf_out,strlen(buf_out),&bc,NULL); CloseHandle(port2); } return 0; } В общем на сом1 идет строка: +) 000,0kg На сом2 нужно отправить: А(русская) 00000.0 B(англ) \r\n (возврат коретки + перевод строки) На HEX это должно так: 80 20 значение цифр 20 42 20 20 0D 0A |
|||
|
||||
| bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 4 Всего: 47 |
F_W
Я бы организовал два треда. Первый, который бы читал ассинхронно данные из порта, второй - записывал в порт. Сейчас подниму свои исходники... |
|||
|
||||
| cardinal |
|
|||
![]() Инженер ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 6003 Регистрация: 26.3.2002 Где: Германия Репутация: 1 Всего: 99 |
F_W, а я бы организовал один тред Он будет слушателем. В нем крутиться постоянно цикл (со switch внутри, которые позволяет войти нашему треду в разные режимы; стандартный режим слушания это status = 0) и слушает. Как что-то услышал переключает переменную (создай одну глобальную volatile под именем status) status (switch = 1 например) и по switch'у мы перейдем в режим посылки на другой порт. После посылки switch = 0 и мы опять слушаем. bel_nikita, такой способ организации ИМХО имеет одно большое преимущество: мы управляем всем тредом одной глобальной volatile переменной. Потом можно даже где-нибудь по нажатию button'а перевести тред в другой режим просто присвоив переменной status другое значение. Точно также можно узнать в любой момент в какой режиме находится наш поток. Добавлено @ 20:27 Модератор: Название темы должно отражать ее суть! -------------------- Немецкая оппозиция потребовала упростить натурализацию иммигрантов В моем блоге: Разные истории из жизни в Германии "Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино". А. и Б. Стругацкие |
|||
|
||||
| Goldberg |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 122 Регистрация: 3.6.2004 Репутация: нет Всего: нет |
2 F W
Т.е. у тебя ReadFile(port1,&buf1,100,&bc,NULL); - находится в цикле? Добавлено @ 22:15 Строка которую ты читаешь, всегда одного размера? Это сообщение отредактировал(а) Goldberg - 11.12.2004, 22:10 --------------------
Вот такая у меня привычка, браться за задание, о выполнение которого я изначально не имею никакого представления. |
|||
|
||||
| bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 4 Всего: 47 |
cardinal
Позволю не согласиться с тобой Видение реализации задачи, ИМХО: Полнофункциональный класс для работы с портом. Создал два объекта. Потокобезопасный буффер, можно за основу STL контейнер какой-нить. Создал бы два треда. Один эвент(событие), можно с автосбросом. Один тред на просшлушке, второй в ожидании на событие. Тред, который слушает порт, читает данные и кладет их в буффер и кидает событие(евент). Второй тред(который пишет в порт), находится в ожидании события. И как только он получил событие, читает буфер, делает нужные преобразования прочтенных данных и пишет в порт. Второй тред, в это время читает следующую порцию данных. Т.е. более эфективное управление ресурсами получаем. Конечно, можно сказать, а нафига ж так сложно? В общем, можно долго философствовать, но человеку от этого не легче. F_W а что за ошибка(конкретнее)? можно на цикл взглянуть? Это сообщение отредактировал(а) bel_nikita - 13.12.2004, 00:22 |
|||
|
||||
| cardinal |
|
||||
![]() Инженер ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 6003 Регистрация: 26.3.2002 Где: Германия Репутация: 1 Всего: 99 |
Это единственная логическая ошибка в твоем рассуждении Процессор у тебя один и одновременно ничего происходить не может. Соответственно "в это время" происходить ничего не будет... Остается только вопрос
-------------------- Немецкая оппозиция потребовала упростить натурализацию иммигрантов В моем блоге: Разные истории из жизни в Германии "Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино". А. и Б. Стругацкие |
||||
|
|||||
| bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 4 Всего: 47 |
cardinal
Так и знал. Хотел же вставить строчки, что реального рапараллеливания не будет, но решил все же не стоит, ведь пишу пост на профи форум Как раз ошибки нет. Потоки, да и вцелом многозадачность, нужны для эфективного распределения и управление ресурсами. Что в данном случае мы и получаем В примере возможной реализации, который я привел, второй ресурс не простаивает, во время обработки/работы первого. Идет постоянное переключение между процесами, тредами и т.д. Т.е. для каждого треда выделяется кванты времени. В итоге мы получаем "распараллеливание". Хотя реально, физически, на однопроцессорной системе его нет. Есть один БОЛЬШОЙ плюс - эфективное управление ресурсами! Вот, смотри. На ком порт непрерывно, постоянно идут данные. Как в таком случае отправлять данные? Т.е. мы не эффективно используем ресурсы. Мы только принимаем, принимаем и принимаем, а второй ресурс у нас простаивает. А при "распараллеливании" мы уже сможем отправлять данные. Т.к. будет постоянное переключение между тредами. Т.е. эффективность. ЧТД ( что и требовалось доказать ) З.Ы.: вроде более-менее понятно написал Это сообщение отредактировал(а) bel_nikita - 13.12.2004, 01:40 |
|||
|
||||
| cardinal |
|
||||
![]() Инженер ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 6003 Регистрация: 26.3.2002 Где: Германия Репутация: 1 Всего: 99 |
Какое же оно эффективное?
А это вообще-то тоже время занимает -> то есть жрет наши ресурсы. Если сделать как я предложил, то процесс "принял-послал" будет работать быстрее. -------------------- Немецкая оппозиция потребовала упростить натурализацию иммигрантов В моем блоге: Разные истории из жизни в Германии "Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино". А. и Б. Стругацкие |
||||
|
|||||
| bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 4 Всего: 47 |
Ну-ну...
|
|||
|
||||
| cardinal |
|
|||
![]() Инженер ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 6003 Регистрация: 26.3.2002 Где: Германия Репутация: 1 Всего: 99 |
А поподробней?
-------------------- Немецкая оппозиция потребовала упростить натурализацию иммигрантов В моем блоге: Разные истории из жизни в Германии "Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино". А. и Б. Стругацкие |
|||
|
||||
| F_W |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 3 Регистрация: 10.12.2004 Репутация: нет Всего: нет |
Получается, что начиная с readfile и до конца нужно поместить в цикл. Но проблема заключается в обработке строки. Без обработки програ ведет себя нормально. А так вызывает ошибку, в которой говорится, что прога будет закрыта, без объяснений. Строка считывается всегда одного формата. + ко всему когда хоть какой-нибудь код ставишь после readfile, то прога начинает принимать с ошибками (это выражается в деформации формата строки).
|
|||
|
||||
| En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: нет Всего: 20 |
bel_nikita
Ты совершенно прав... Если делать, по методу cardinal'а, то возможно на несколько кб. виртуальной памяти ты получишь выгоду, но проц. будет работать в усиленном режиме. Наверно не в тему: Но вот пример, когда лучше организовать два треда, привёл первое попавшееся в мозг... long int a = 9999999; //глобальные переменные обьявленные в двух //критических точках long int b = 9999999; также файл ofstream out; UINT My_thread(LPVOID pParam) { //везде надо делать операции, как с крит. точками...! for(; a > 0; a--) { b++; return 0; // еслит перед возвращением поставить таймер, результат которого можно с легкость вывести, то можно определить время выполнения потока... } } UINT My_two(LPVOID pParam) { while(проверяем живёт ли поток My_thread) { out << a; //если правильно всё сделать с крит. точками, то в переменные должны ассинхронно падать данные из первого потока(оба потока обсалютно паралельны) out << b; } return 0; } Теперь сверяем таймер и время последнего изменения файла... Запоминаем результат... А теперь вот такой код: .... for(; a > 0; a--) { out << a; b++; out << b; } ....... Соответсвенно измеряем время выполнения оперции, сравниваем результаты, и радуемся Два треда - лучший выход в данной ситуации... а если бы все так думали, как cardinal , то у процесса system в НТ было бы всего два паралельных потока, а их у него минимум 41... Это сообщение отредактировал(а) En_t_end - 14.12.2004, 08:28 |
|||
|
||||
| cardinal |
|
|||
![]() Инженер ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 6003 Регистрация: 26.3.2002 Где: Германия Репутация: 1 Всего: 99 |
En_t_end, я уж думал как провести эксперимент с двумя com-портами, но теперь у меня есть твой код и как-нибудь на выходных я с ним поковыряюсь
Своей неправоты я не исключаю, но пока отсаюсь при первоначальном мнении
Ну ты сказал... Еще бы сказал, что если бы все думали как я, то windows был бы dos'ом. -------------------- Немецкая оппозиция потребовала упростить натурализацию иммигрантов В моем блоге: Разные истории из жизни в Германии "Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино". А. и Б. Стругацкие |
|||
|
||||
| En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: нет Всего: 20 |
"поковыряюсь..."
Да кстати в MFC есть класс ассинхронной работы с com... "Ну ты сказал... Еще бы сказал, что если бы все думали как я, то windows был бы dos'ом." Нет я имел в виду, что способ : получил-отправил, организованный в одном потоке, также мог быть использованн в НТ-ях, но представь себе, что несколько сервисов(20-30) будут организованны в виде цикла, и только после прохождения всего цикла система получит результат необходимых элементов : очень медленно, + цикл будет использовать туеву тучу проц. времени... |
|||
|
||||
| cardinal |
|
|||
![]() Инженер ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 6003 Регистрация: 26.3.2002 Где: Германия Репутация: 1 Всего: 99 |
Ну мы в данном случае обсуждаем ИМХО немного другую ситуацию... -------------------- Немецкая оппозиция потребовала упростить натурализацию иммигрантов В моем блоге: Разные истории из жизни в Германии "Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино". А. и Б. Стругацкие |
|||
|
||||
| En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: нет Всего: 20 |
"Ну мы в данном случае обсуждаем ИМХО немного другую ситуацию..."
Ну дык я поясняю свою оффтопную фразу |
|||
|
||||
![]()
|
| Правила форума "C/C++: Системное программирование и WinAPI" | |
|
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |