Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > обрушивается многопоточная программа


Автор: hexzo 12.10.2011, 09:50
Обрушивается многопоточная программа. Схема приблизительно такая.

класс гуя {
  Sender* sender; //класс умеющий принимать сетевые сообщения
  конструктор_формы {
    receiveTcpMessageThread.putSender(sender); // я треду передаю экземпляр класса, метод которого он должен вызвать.
  }
  обработчик_кнопки {
   receiveTcpMessageThread.start(); //стартую тред
  }
}

класс receiveTcpMessageThread {
  run() {
   receiverref->startTcpListening();
  }
}

И в результате происходит какая то хрень
Предсмертное сообщение программы: QSocketNotifier: socket notifiers cannot be disabled from another thread
Обваливается всё на строчке? которая содержится в классе Sender:
Код

QTcpSocket *socket = tcpserver->nextPendingConnection();


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

Добавлено через 4 минуты и 38 секунд
Есть ещё такой извращённый вариант на крайний случай - завести в классе треда экземпляр Sender-а. Но тогда встаёт вопрос, как в треде не связанном с гуишным сделать
Код

   QLabel* label = new QLabel(result);
    label->setAttribute(Qt::WA_DeleteOnClose);
    label->setWordWrap(1);
    label->setStyleSheet("font: bold 14px;");
    label->show();

Потому как ошибка:
"Widgets must be created in the GUI thread."

Автор: hexzo 12.10.2011, 10:29
hexzo 
Цитата
Но тогда встаёт вопрос, как в треде не связанном с гуишным сделать

Есть такой извращённый вариант, перенести этот код в слот объекта привязанного к главному треду и соответственно вызывать его через сигнал.

Автор: hexzo 12.10.2011, 11:04
А ещё можно вызывать в треде нужный метод сигналом. smile
Так почему-то работает. По идее start_tcp_listening() должно срабатывать в треде гуишного потока, потому что receiverref привязан к нему, поскольку он в нём создавался. Но интерфейс почему-то не тормозится. А почему, я уже запутался.  smile 

Код

void TcpServerThread::run()
{
  connect(this,SIGNAL(run_this()),receiverref,SLOT(start_tcp_listening()));
  emit run_this();
  connect(receiverref,SIGNAL(send_received_message(QString)), owner,SLOT(make_notify_message(QString)));
}

Автор: hexzo 12.10.2011, 12:36
Цитата

По идее start_tcp_listening() должно срабатывать в треде гуишного потока, потому что receiverref привязан к нему

Оно там и выполняется. А интерфейс не тормозился потому что у меня там выполнялось всё быстро. smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)