У меня раздражающая проблема с Qt и многопоточностью.Ниже я создал упрощенный код.В моем реальном коде принцип точно такой же, но слишком сложный, следовательно, для использования упрощенной версии.
Проблема заключается в том, что приложение случайным образом завершает работу в разные моменты времени во время выполнения с разными сообщениями:
free(): invalid pointer
double free or corruption
Сбой запускается изнутри Qt, я объясню в концепост.
Вот как работает код.
Итак, у меня есть classA , который запускает поток:
class classA
{
public:
void start();
boost::function<void (std::string)> __ptr; // for callback
private:
boost::thread * thread;
void run();
};
void classA:start()
{
thread = new boost::thread(&classA::run, this); // start the thread
}
и вот фактический методкоторый запускается в отдельном потоке:
void classA::run()
{
for (int i = 0; i < 50000; i++)
{
static int count = 0;
__ptr("test123" + std::to_string(++count));
}
}
В моем QDialog
унаследованном классе у меня есть простой метод, который назначает boot::function
, поэтому я объявил еще один boost::function
ptr.Проблема не в ptr, а в Qt, читай дальше, обратный вызов работает просто отлично ...
class myClassB : public QDialog
{
Q_OBJECT
public:
explicit myClassB (QWidget *parent);
classA ca;
private:
boost::function<void (std::string)> __ptr;
void mycallback(std::string);
};
В конструкторе myClassB я назначаю свойперезвоните на boost::function
вот так (как я уже говорил, обратный вызов работает нормально).
myClassB::myClassB()
{
this->__ptr = ( boost::bind( &myClassB::mycallback, this, _1 ) );
ca.__ptr = __ptr;
}
Вот здесь и начинается проблема.При обратном вызове в моем QDialog класса B я излучаю сигнал Qt
void myClassB::mycallback(std::string txt)
{
emit sig_qt_data_received(txt);
}
Этот сигнал подключается в конструкторе моего класса B:
connect(this, SIGNAL(sig_qt_data_received(std::string)), this, SLOT(data_received(std::string)), Qt::DirectConnection);
и, наконец, реализация слота Qt:
void myclassB::data_received(std::string txt)
{
ui->lbl_status->setText(txt);
}
Вот в чем проблема:
Если удалить ui->lbl_status->setText(txt);
, программа работает без сбоев, она никогда не падает,если вы оставите его, он случайно вылетает:
free(): invalid pointer
double free or corruption
Похоже, что проблема в Qt, так как когда я удаляю ссылки на setText (), он не падает, и япочти каждая процедура многопоточности GUI, которую я нашел, и я не знаю, что я делаю неправильно.
Для подключения сигнала Qt я использую Qt::DirectConnection
, и если я использую Qt::AutoConnection
, он будетработать без сбоев , но иногда весь пользовательский интерфейс зависает (Редактировать: это неверно, см. мой ответ ).
Я надеюсь, что кто-то может помочь.Если вам нужно больше кода / реального кода, дайте мне знать, я напишу фактический исполняемый код, который вы можете запускать и компилировать, но основы те же, вот как работает код.
Я не хочуиспользовать QThread.