Russian Qt Forum
Май 23, 2024, 07:37 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] QNetworkAccessManager: неверная работа с тредами валит приложение  (Прочитано 2992 раз)
billygates
Гость
« : Февраль 25, 2010, 13:33 »

Есть следующее (псевдо-код):

Код
C
class RequestMaker: public QObject
{
  Q_OBJECT
  private:
    QNetworkAccessManager mgr_;
  public:
    RequestMaker(QObject* parent) : QObject(parent), mgr_(this)
    {
       connect(&mgr_, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkReplyReceived(QNetworkReply*)));
    }
    void sendRequest(...)
    {
        // compose request
        mgr_.post(...);
    }
  public signals:
     void responseReceived(Response*);
  private slots:
     void networkReplyReceived(QNetworkReply* reply)
     {
         // convert reply to a special struct
         Response* resp = ResponseMaker::make(reply);
         emit responseReceived(resp);
         reply->deleteLater();
     }
};
 

Данный класс используется в MainWindow: public QMainWindow, устанавливая слот на responseReceived(). Выполняет sendRequest() и в слоте responseReceived() делает widget.update(). После чего seg. fault.

Подозреваю, что слот выполняет в другом треде, и из-за этого такое поведение. Как заставить нормально отрабатывать данный сценарий с данным кодом? Может в каком-то месте надо сделать moveToThread() ?

Спасибо.
« Последнее редактирование: Февраль 25, 2010, 16:00 от billygates » Записан
voronElf
Гость
« Ответ #1 : Февраль 25, 2010, 14:07 »

Цитировать
Подозреваю, что слот выполняет в другом треде
тред тот же самый, если конечно ты сам за рамками этого кода с тредами не играешься. QNetworkAccessManager у меня отрабатывает нормально безо всяких moveToThread().

Я бы в первую очередь обратил внимание на то, что на основе reply создается resp, а reply сразу грохается. в resp нету укателей на данные из reply (уже удаленного на момент обращения) ?
Записан
billygates
Гость
« Ответ #2 : Февраль 25, 2010, 14:21 »

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

С тредами не играю: исключительно последовательные вызовы. gdb показывает, что создается несколько нитей:
Код:
- sendRequest()
[New Thread 0xb77ddb70 (LWP 13839)]
здесь же вызывается networkReplyReceived(QNetworkReply*)
[New Thread 0xb6fdcb70 (LWP 13840)]
еще одно сообщение (via qDebug) от networkReplyReceived(QNetworkReply*)

Я бы в первую очередь обратил внимание на то, что на основе reply создается resp, а reply сразу грохается. в resp нету укателей на данные из reply (уже удаленного на момент обращения) ?

Response не содержит указателей. Абсолютно статичные данные --  специально так проектировался.
Падает именно в той точке, где выполняется метод визуального виджета. По симптомам -- очень похоже на случай, когда из другого треда пытаются воздействовать на виджет, находящийся в другом потоке.
Записан
billygates
Гость
« Ответ #3 : Февраль 25, 2010, 16:00 »

Сам дурак. Вопрос снят. Всем спасибо!

Указатель на виджет был obsolete (до этого он был перемещен в другое пространство имен, а старый остался), соответственно он нигде не инициализировался, отсюда и seg. fault.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.05 секунд. Запросов: 17.