Russian Qt Forum

Qt => Вопросы новичков => Тема начата: demaker от Сентябрь 04, 2015, 12:47



Название: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 12:47
Есть простейшая программа обработки портов

Код
C++ (Qt)
Thread::Thread(QObject * parent): QThread(parent)
{
}
 
Thread::~Thread()
{
qDebug()<<__FUNCTIOIN__;
}
 
void Thread::run()
{
   while(1)
   {
       msleep(3);
       handlePress();        
   }
}
 
void Thread::handlePress()
{
 
// опрос портов
}
 
 
 
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);    
 
   counter = 0;
   thread = NULL;
 
   if(initNumberLineGPIO() && initDirectionLineGPIO())
   {
       thread = new Thread();
       thread->start();
   }
}
 
MainWindow::~MainWindow()
{
   delete ui;
 
   if(thread != NULL){
     thread->quit();
     thread->wait();
     delete thread;
  }
}
 

Но выдается ошибка
Код:
 QThread: Destroyed while thread is still running

хотя в деструктор Thread заходит, но сам процесс не убивается
не могу понять почему???


Название: Re: Потоки
Отправлено: Old от Сентябрь 04, 2015, 12:56
Потому, что quit завершает цикл обработки событий потока, а вы его даже не запускаете.
Добавляйте свой флажок завершения бесконечного цикла в run.


Название: Re: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 13:17
Ожидал такого ответа.
Ну если правильно понял Вас )

делаю так
Код
C++ (Qt)
 
Thread::Thread(QObject * parent): QThread(parent)
{
 flag = true;
}
 
void Thread::run()
{
   while(flag)
   {
       msleep(3);
       handlePress();        
   }
}
 
 
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);    
 
   counter = 0;
   thread = NULL;
 
   if(initNumberLineGPIO() && initDirectionLineGPIO())
   {
       thread = new Thread();
       thread->start();
   }
}
 
MainWindow::~MainWindow()
{
   delete ui;
 
   if(thread != NULL){
     flag = false;
     thread->quit();
     thread->wait();
     delete thread;
  }
}
 

но выдается все таже ошибка
Код:
QThread: Destroyed while thread is still running


Название: Re: Потоки
Отправлено: Old от Сентябрь 04, 2015, 13:19
Лучше flag сделать членом Thread и quit можно не вызывать.


Название: Re: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 13:28
))
И так делал как Вы сказали
Вот код
Код
C++ (Qt)
class Thread: public QThread{
 
public:
bool flag;
}
 
Thread::Thread(QObject * parent): QThread(parent)
{
 flag = true;
}
 
void Thread::run()
{
   while(flag)
   {
       msleep(3);
       handlePress();        
   }
}
 
 
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);    
 
   counter = 0;
   thread = NULL;
 
   if(initNumberLineGPIO() && initDirectionLineGPIO())
   {
       thread = new Thread();
       thread->start();
   }
}
 
MainWindow::~MainWindow()
{
   delete ui;
 
   if(thread != NULL){
     thread->flag = false;
     delete thread;
  }
}
 

Но не помогает ((


Название: Re: Потоки
Отправлено: Old от Сентябрь 04, 2015, 13:33
Код
C++ (Qt)
MainWindow::~MainWindow()
{
   delete ui;
 
   if(thread != NULL){
     thread->flag = false;
     thread->wait();                        // !!! wait нужен
     delete thread;
  }
}
 

И что находится в handlePress?


Название: Re: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 13:39
Да конечно Вы правы!
Не убрал))
wait()
Код
C++ (Qt)
#define CNT_SAMPLE_MAX 4
#define CNT_SAMPLE_MIN 0
#define MAX_LINE_EVENT 10
 
typedef struct{
   int cnt_sample;//schetchik viborki
   int cnt_event_up; //schetchik sobitii
   int cnt_event_down;
   bool flag;
}gpio_line;
 
Код
C++ (Qt)
int number_gpio_line[amount_line] = {416,417,418,419,
                                    420,421,422,423,
                                    424,425,426,427,
                                    428,429,430,431,
                                    433,
                                    435,
                                    436
                                   };
 
 
gpio_line array_gpio_line[amount_line] = {{0,0,0,false},{0,0,0,false},{0,0,0,false},{0,0,0,false},
                                         {0,0,0,false},{0,0,0,false},{0,0,0,false},{0,0,0,false},
                                         {0,0,0,false},{0,0,0,false},{0,0,0,false},{0,0,0,false},
                                         {0,0,0,false},{0,0,0,false},{0,0,0,false},{0,0,0,false},
                                         {0,0,0,false},
                                         {0,0,0,false},
                                         {0,0,0,false}
                                        };
 
 
Код
C++ (Qt)
void Thread::handlePress()
{    
   for(int i = 0; i < amount_line; i++){
       QFile file;
       QDir::setCurrent("/sys/class/gpio/gpio" + QVariant(number_gpio_line[i]).toString());
       file.setFileName("value");
 
       if(file.open(QIODevice::ReadOnly)){
           QByteArray ba;
           ba = file.readAll();
           if(ba.at(0) == '1'){
               if(array_gpio_line[i].cnt_sample < CNT_SAMPLE_MAX){
                   array_gpio_line[i].cnt_sample++;
               }
               else if(!array_gpio_line[i].flag){
                   array_gpio_line[i].flag = true;
                   if( array_gpio_line[i].cnt_event_up < MAX_LINE_EVENT){//security counter
                       array_gpio_line[i].cnt_event_up++;
                   }
               }
           }
           else{
               if(array_gpio_line[i].cnt_sample > CNT_SAMPLE_MIN){
                   array_gpio_line[i].cnt_sample--;
               }
               else if(array_gpio_line[i].flag){
                   array_gpio_line[i].flag = false;
                   if( array_gpio_line[i].cnt_event_down < MAX_LINE_EVENT){//security counter
                       array_gpio_line[i].cnt_event_down++;
                   }
               }
           }
           file.close();
       }
       else{
           qDebug("file is not open");
       }
   }
}
 

Но к сожалению  в консоль выводится что программа завершилась
это уже лучше)))

но КРАХОМ ((
 



Название: Re: Потоки
Отправлено: Old от Сентябрь 04, 2015, 13:42
И еще вопрос. Вы уверены, что это сообщение выдается при разрушении именно этой нитки? Может есть другие?
Попробуйте за комментировать создание этой нитки - останется сообщение или нет?


Название: Re: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 13:54
Ну я только создаю только одну нитку - Thread. Конечно есть main ))

Давайте я скину проект)
Так будет проще



Название: Re: Потоки
Отправлено: Old от Сентябрь 04, 2015, 13:57
ok


Название: Re: Потоки
Отправлено: PimenS от Сентябрь 04, 2015, 13:57
Цитировать
while(flag)
    {
        msleep(3);
        handlePress();        
    }

это так и задумано, чтобы handlePress() выполнялся бесконечно?


Название: Re: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 14:03
 :)


Название: Re: Потоки
Отправлено: Old от Сентябрь 04, 2015, 14:14
Добавьте в конструкторе MainWindow инициализацию thread:
Код
C++ (Qt)
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
ui(new Ui::MainWindow),
thread( 0 )
{
...
}
 

А в деструктор код завершения нитки.


Название: Re: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 14:39
А что
такая запись не катит
Код
C++ (Qt)
thread = new Thread();
 

 ???


Название: Re: Потоки
Отправлено: Old от Сентябрь 04, 2015, 14:40
А что
такая запись не катит
Код
C++ (Qt)
thread = new Thread();
 

 ???
А если
if(initNumberLineGPIO() && initDirectionLineGPIO())
вернет false? :)


Название: Re: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 14:44
Да согласен :) - логично.

Но аппаратно это не может произойти.

и если так произойдет, то
Код:
thread = NULL

и норм ))


Название: Re: Потоки
Отправлено: Old от Сентябрь 04, 2015, 14:47
У меня нет gpio, поэтому я тут-же получил при разрушении MainWindow. :)
А так все работает.


Название: Re: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 14:49
Я работаю под Linux.
А Вы?


Название: Re: Потоки
Отправлено: Old от Сентябрь 04, 2015, 14:50
Я работаю под Linux.
А Вы?
И я.


Название: Re: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 14:54
 :) замечательно

Ну а если закоментить вызов handlePress() в потоке
и просто вызывать указатель на поток в объекте класса MainWindow то все норм


Название: Re: Потоки
Отправлено: Old от Сентябрь 04, 2015, 14:56
:) замечательно

Ну а если закоментить вызов handlePress() в потоке
и просто вызывать указатель на поток в объекте класса MainWindow то все норм
Я просто закомментировал
f(initNumberLineGPIO() && initDirectionLineGPIO())
в конструкторе.
Нитка нормально создается и завершается.


Название: Re: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 15:02
Ну-у-у :)

у меня все равно выдает в консоль дебаг
Код:
QThread: Destroyed while thread is still running
когда я закрываю окно MainWindow


Название: Re: Потоки
Отправлено: Old от Сентябрь 04, 2015, 15:04
Попробуйте исправить даты у файлов и перекомпилировать весь проект. Мне пришлось даты у файлов менять, а то вы как из глубокого будущего, 2028 год все таки. :)


Название: Re: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 15:06
)))))))))))))))))))))))))))))))))
сча попробую


Название: Re: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 15:08
Хотя какая разница ?


Название: Re: Потоки
Отправлено: Old от Сентябрь 04, 2015, 15:09
Хотя какая разница ?
Возможно mainwindow.cpp не компилируется при изменении файла?


Название: Re: Потоки
Отправлено: Tuxford от Сентябрь 04, 2015, 15:25
Попробуйте сначала закоментить handlePress() и все что работает с gpio, начиная с инициализации. Есть крэш?


Название: Re: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 15:32
У меня IceWM как в ней поменять дату и время ?


Название: Re: Потоки
Отправлено: demaker от Сентябрь 04, 2015, 15:52
Сделал, но не помогло


Название: Re: Потоки
Отправлено: Old от Сентябрь 04, 2015, 15:54
Сделал, но не помогло
Вот так у меня работает.


Название: Re: Потоки
Отправлено: Fregloin от Сентябрь 07, 2015, 10:25
при завершении потока пробуйте так
thread.quit();
thread.wait();


Название: Re: Потоки
Отправлено: demaker от Сентябрь 07, 2015, 11:50
Я даже коменты убрал
работает :)

Спасибо)

И  процесс вроде убивается, т.е в линуксовую консоль в списоке его нет

А дебаг выводит свой стандартный месадж(