Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> COM порт и потоки 
:(
    Опции темы
Ilya83
Дата 16.12.2017, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 5.1.2014

Репутация: нет
Всего: нет



Всем привет. Прошу помощи! 

Есть программа считывающая данные с ком порта и записывающая в файл. у проги 1 кнопка старт(она же стоп).

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

я добавил поток winapi и вынес туда цикл сбора данных. теперь прога не тормозит, но появились 2 проблемки:

1) прога записывает в файл не новые данные с порта, а записывает каждую итерацию проги(потока)

2) на кнопку старт можно нажать только 1 раз. При нажатии на кнопку 2-ой раз программа зависает и вылетает.

функция потока:

Код

DWORD WINAPI threadFunc(LPVOID t){
    
     if(!comPort.isRead()){ 
                       
            buffArr[i] = comPort.getData();
            
            if(buffArr[i] != '\r'){
                if(buffArr[i] != '\n'){
                    strFromBuff[i] = buffArr[i];
                     
                    i++;}}else{
                
                    strBuff = strFromBuff;      
                  
                    i=0;               
                      
                }//else fuffArr
         
        }else{
            comPort.close();
            MessageBox(NULL, "Not oK", "Error", MB_OK);
        }//if
    
    return 0;
}


функция нажатия на кнопку:
Код

void startStopBtnClicked(GtkWidget *widget, gpointer data){
   
    if(!isBtnClicked){
       
        btnLabel = "Stop";
        gtk_button_set_label(GTK_BUTTON(startStopBtn), btnLabel);
        isBtnClicked = TRUE;
        isStopped = FALSE;
        
        comPort.create();
        comPort.init();
        
        char timeBuffer[80];
        time_t seconds = time(NULL);
        tm* timeinfo = localtime(&seconds);
        char* format = "%d_%B_%Y_%I_%M_%S";
        strftime(timeBuffer, 80, format, timeinfo);
        
        fout.open(strncat(timeBuffer, ".txt", 4));
        
        while(!isStopped){
            
            while(gtk_events_pending()) gtk_main_iteration();
            
            HANDLE thread = CreateThread(NULL, 0, threadFunc, NULL, 0, NULL);
           
            fout << strBuff << "\n";            
            gtk_text_buffer_set_text(buffer, strBuff, -1);
            
        }//while isStopped
        
    }else{
        comPort.close();
        isStopped = TRUE;
        btnLabel = "Start";
        gtk_button_set_label(GTK_BUTTON(startStopBtn), btnLabel);
        isBtnClicked = FALSE;
    }
    fout.close(); 
}




Подскажите пож. как исправить

Это сообщение отредактировал(а) Ilya83 - 16.12.2017, 15:34
PM MAIL   Вверх
Romikgy
Дата 16.12.2017, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7325
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 1
Всего: 146



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


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Ilya83
Дата 17.12.2017, 08:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 5.1.2014

Репутация: нет
Всего: нет



Похоже Вы правы. Прога зависает на строчке закрытия порта

 
Код

 void close(){
        CloseHandle(hPort);
    }


Подскажите, как поправить ? Может мне надо как-то корректно завершить поток ???

Это сообщение отредактировал(а) Ilya83 - 17.12.2017, 08:48
PM MAIL   Вверх
xvr
Дата 18.12.2017, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Ваш поток читает из порта 1 символ и завершается. Это так и задумывалось?

PM MAIL   Вверх
Ilya83
Дата 18.12.2017, 23:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 5.1.2014

Репутация: нет
Всего: нет



Нет, читает строку где-то 100 байт. Вопрос не в этом. Вопрос в том, что эти байты читаются в отдельном потоке. А в основном потоке CloseHandle(hPort) (стр.33) не работает. Программа зависает. 

Надо как-то закрыть порт при нажатии на кнопку стоп. Но я не знаю как это сделать.
PM MAIL   Вверх
Romikgy
Дата 19.12.2017, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7325
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 1
Всего: 146



сообщение отправьте потоку .... иль глобальный флаг сделайте ...


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
xvr
Дата 19.12.2017, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(Ilya83 @  18.12.2017,  23:53 Найти цитируемый пост)
Нет, читает строку где-то 100 байт. 

Неа, не читает. У вас в функции потока (threadFunc) нет ни одного цикла. Так что считать более чем 1 символ ваш поток не может.
Другое дело, что вы эти потоки запускаете постоянно (в цикле) - стр 21-30 в обработчике нажатия на кнопку. Тем самым блокируя обработчик, кстати.
Так многопоточные программы не пишут (кстати, многопоточные - это не значит, что в ней действительно должно быть МНОГО потоков, вполне достаточно будет двух)

Ваш поток должен полностью включать в себя всё взаимодейтсвие с портом и файлом. Внутри потока должен выполняться бесконечный цикл, который читает порт и пишет прочтенное в файл.

При первом нажатии startStopBtnClicked должен стартовать поток (функцией CreateThread), после чего обработчик должен немедленно закончится
При втором нажатии, поток должен быть остановлен и завершен (для этого можно воспользоваться Event'ом). Обработчик кнопки опять ничего ждать не должен

И ещё вопрос - если вся прога состоит из потока и одной кнопки, почему было не сделать обычную консольную утилиту, и не заморачиваться с GUI и потоками?

PM MAIL   Вверх
Ilya83
Дата 19.12.2017, 22:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 5.1.2014

Репутация: нет
Всего: нет



Цитата

Неа, не читает. У вас в функции потока (threadFunc) нет ни одного цикла.


Только так у меня получилось вывести в отдельный поток, иначе у меня GTK ругалась. я не понял почему. Что-то вроде низя вот так вот обращаться из основного потока GTK в отдельный поток. Там с потоками вообще что-то странное получилось. Как я понял, у GTK потоки как-то совсем хитро работают. А в windows вообще никто не знает точно, как они работают и работают ли вообще. Буду пробовать перенести цикл в поток.

Цитата

Другое дело, что вы эти потоки запускаете постоянно (в цикле) - стр 21-30 в обработчике нажатия на кнопку.


Да, меня это заинтересовало

Код

while(!isStopped){
            
            while(gtk_events_pending()) gtk_main_iteration();
            
            HANDLE thread = CreateThread(NULL, 0, threadFunc, NULL, 0, NULL);
            
        }


Запустил прогу где-то на 20 мин. и смотрел в диспетчере задач. Думал там память будет расти, потоки же создаются в цикле бесконечном. Ан нет. Хотелось бы знать почему, ведь не могут же эти потоки плодится бесконечно. эти потоки весчь виртуальная что ли? Или очень умный компилятор что-то свое мудрит и подставляет вместо моего гумнокода ????  smile 

Цитата

Тем самым блокируя обработчик, кстати.


Неа, там 

Код

while(gtk_events_pending()) gtk_main_iteration();


Костыль, гумно код, я знаю  smile 

xvr, Вы можете объяснить почему в данном случае CloseHandle(hPort); зависает ? Если вставить CloseHandle(hPort); в поток, то он выполняется. Если убрать поток, то CloseHandle(hPort); выполняется в основном потоке. А вот вызов из главного потока CloseHandle(hPort); в данном варианте зависает. Почему ????

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

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

Цитата

Так многопоточные программы не пишут


Ну вот будут выходные, постараюсь изучить материал на тему "потоки в С++" Обещаю!  smile 

Ну может подскажите, как выкрутиться в данном случае. Где костыль поставить тк сказать. У меня же и на экран выводиться из потока и в файл записывается из потока. Мнеб только кнопкой стоп остановить этот поток и все! прога работает! 

Код

if(!comPort.isRead()){      
                       
            buffArr[i] = comPort.getData();
            
            if(buffArr[i] != '\r'){
                if(buffArr[i] != '\n'){
                    strFromBuff[i] = buffArr[i];
                     
                    i++;}}else{
                
                    strBuff = strFromBuff;                  
                                    
                    i=0;  
                    
                    if(i <= 0){
                        fout << strBuff << "\n";            
                        g_timeout_add(1000, (GSourceFunc)time_handler, (gpointer)window);
                                              
                    }
                      
                }//else fuffArr
         
    }else{
            comPort.close();
            MessageBox(NULL, "Not oK", "Error", MB_OK);
         }//if



Цитата

И ещё вопрос - если вся прога состоит из потока и одной кнопки, почему было не сделать обычную консольную утилиту,


Ой, действительно... smile

Добавлено через 3 минуты и 39 секунд
Цитата

сообщение отправьте потоку .... иль глобальный флаг сделайте ... 


я пробовал флаги ставить и поток убивать. Ставил запрещенную смертельную функцию, которую все программисты бояться использовать

Код

BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode);


Не работает  smile 

Ну может я не там ее ставил. Как выше уже говорил, без отладчика не понимаю, как программа работает. Надо с отладчиком разобраться иначе...  smile 
PM MAIL   Вверх
Ilya83
Дата 19.12.2017, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 5.1.2014

Репутация: нет
Всего: нет



Хаха Перенес цикл while в поток и все , вроде бы, заработало как надо   smile Ща буду тестить.....

Я вот сейчас попробовал 2-а варианта:

просто 
Код

CloseHandle(hPort)


и

Код

TerminateThread(thread, 0);
CloseHandle(hPort)


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

Там еще есть какая-то разница между потоками и процессами.....

И остался вопрос, как я так в бесконечном цикле (да еще и в обработчике) создавал потоки ??? Неужели действительно умный компилятор за меня код переписывал  smile  Ох, буду разбираться, как работают потоки.

Ребят, выручайте! подскажите, как решить проблему с отладчиком. Не возможно делать трассировку. Вылетает ошибка:  "Signal received: SIGTRAP (Trace/breakpoint trap). Как от этого избавиться??? Без отладчика изучать С++ безсмысленно  smile  

PS: Плюсануть Вам не могу. Не дорос еще.


Это сообщение отредактировал(а) Ilya83 - 19.12.2017, 23:27
PM MAIL   Вверх
xvr
Дата 20.12.2017, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(Ilya83 @  19.12.2017,  22:07 Найти цитируемый пост)
 Хотелось бы знать почему, ведь не могут же эти потоки плодится бесконечно. эти потоки весчь виртуальная что ли? 

Они не плодятся. Вы запускаете поток, он читает 1 символ и  тутже завершается. Так что в полёте находится немного потоков.

Цитата(Ilya83 @  19.12.2017,  22:07 Найти цитируемый пост)
xvr, Вы можете объяснить почему в данном случае CloseHandle(hPort);

Не могу. В исходном коде нет ни CloseHandle ни hPort, так что саказть что с ними не так не представляется возможным

Цитата(Ilya83 @  19.12.2017,  22:07 Найти цитируемый пост)
Только так у меня получилось вывести в отдельный поток, иначе у меня GTK ругалась. я не понял почему. Что-то вроде низя вот так вот обращаться из основного потока GTK в отдельный поток. 

Нельзя. Всё взаимодействие между потоком и основной GUI частью должно быть синхронизированно через соотвествующие примитивы (не знаю, что для этого есть в GTK)
Поэтому я и советовал свести его к минимуму - оставить только сигнал, что пора закругляться (его можно реализовать через голые Win32 API вызовы)

Цитата(Ilya83 @  19.12.2017,  23:25 Найти цитируемый пост)
Ребят, выручайте! подскажите, как решить проблему с отладчиком. Не возможно делать трассировку. Вылетает ошибка:  "Signal received: SIGTRAP (Trace/breakpoint trap).

Никак. Это и есть точка останова (breakpoint), оно так работает. смотрите переменные и продолжаете программу дальше.
NB. Надеюсь что программа собрана с отладочной информацией?


PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1675 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.