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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QThread генерирует ошибку до начала выполнения  (Прочитано 9407 раз)
foxexe
Гость
« : Январь 13, 2010, 19:04 »

Я совсем уже опустил руки, создаю классический каркас для треда
Код:
class MyThread: public QThread
{
public
        void run();
};
void MyThread::run()
{
             ....
             exec();
}


запуская такой тред в различных местах программы получаются разные Debugger error со страшными словами типа ASSET и прочее, ну иногда можно добиться вывода такой ошибки QThread: Destroyed while thread is still running
хотя тред то ещё даже не исполнил не одной строчки из своей функции.

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

даже запуск такого треда в фукции main  даёт ошибки, но уже что QWidget должет создаваться только в gui треде.

Qt 4.4.3 VS2008
Записан
Dendy
Гость
« Ответ #1 : Январь 13, 2010, 19:07 »

Покажите как вы создаёте экземпляр этого потока.
Записан
foxexe
Гость
« Ответ #2 : Январь 13, 2010, 19:11 »

пробовал 2 варианта
Код:
MyThread a;
a.start();

Код:
MyThread *a=new MyThread();
a->start();

если создать пустой проект то такие штуки работают.

даже добавид CONFIG += thread хотя это я понимаю не особо важно
Записан
Dendy
Гость
« Ответ #3 : Январь 13, 2010, 19:25 »

Подозреваю, что тред создаётся и запускает run() в другом потоке раньше, чем в вызывающем доходит до конца области видимости. Потом вызывается деструктор потока, в то время как его клавный цикл exec() не был остановлен. По умолчанию ~QThread() его сам не останавливает, поскольку это не гарантирует, что run() завершился корректно - ведь после exec() может быть ещё клиентский код. Вот он и ругается, что поток был прерван с возможными ошибками. Не было бы exec() - всё было бы так же печально, но с отличием, что ~QThread() не смог бы определить, выполняется ли ещё поток или нет. Отловить поведение собственного потока можно только самостоятельно в деструкторе, отправив циклу событий quit() и подождав, пока поток завершится с помощью wait().
Записан
foxexe
Гость
« Ответ #4 : Январь 13, 2010, 19:47 »

Да спасибо, это кстати очень классная догадка, я бы недодумался , но я там всё же создавал по ссылке изначально, на самом деле он ругается что я пользуюсь объектом из другого потока что-ли. я вообще не особо понимаю в чём проблема, просто помню была такая ошибочка, вылезала, и правда убрал все вызовы  лишние работает, только вот как же теперь обратиться к объектам созданным в главном потоке
Записан
Dendy
Гость
« Ответ #5 : Январь 13, 2010, 19:52 »

Непонятно откуда и к чему вы хотите обратиться.
Записан
foxexe
Гость
« Ответ #6 : Январь 13, 2010, 20:08 »

да я кстати щас вот думал как переформулировать и тут такое дело, что в основном потоке создаётся класс Engine, который собственно движок. и вот я в его конструкторе(в отлажочных целях) создаю поток, и обращаюсь к Engine по глобальной ссылке.

main.cpp
Код:
MyEngine *Engine
int main()
{
...
Engine= new MyEngine(...);
...
}


thread.cpp
Код:
extern MyEngine * Engine
MyThread::run()
{
         Engine->method();//вот где собака зарыта
}

у меня сейчас спутанность сознания какая-то и я вобщем вижу что есть в этом кривизна, но в чём именно не пойму.

получается что мне надо общать с этим Engine через сигнал-слоты?

Записан
Dendy
Гость
« Ответ #7 : Январь 13, 2010, 20:36 »

Можно общаться как и сейчас, только гарантировать:

1) Что обьект Engine будет существовать во время обращения к нему.
2) Потокобезопастность метода MyEngine::method().
Записан
foxexe
Гость
« Ответ #8 : Январь 13, 2010, 20:56 »

ну Engine да создан, но method() просто запускает  QTextEdit::append() мне не кажется что это настолько потоконебезопасно, я попробую попозже там мютексы поставить, но что-то мне кажется не в этом то дело.
Записан
Dendy
Гость
« Ответ #9 : Январь 13, 2010, 21:00 »

Этот метод не может быть потокобезопастрым, поскольку QTextEdit::append() уже не reentrant. Его можно вызывать только из главного потока.
Записан
foxexe
Гость
« Ответ #10 : Январь 13, 2010, 21:19 »

так вот гда собака то зарыта!!! ес

а можно узнать что-же происходит если я вызываю её из другого потока?
Записан
Dendy
Гость
« Ответ #11 : Январь 13, 2010, 21:33 »

Race Condition стало быть с непредсказуемыми последствиями.
Записан
foxexe
Гость
« Ответ #12 : Январь 13, 2010, 21:45 »

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

точно точно, отсюда и постоянно разные ошибки, в разных файлах в разных местах
я так понимаю что гонка может произойти при условии что остальные потоки не запускают QTextEdit::append(), внутреняя архитектура тоесть там что-то там-то. А всё-таки как мне обращаться в этим method() тогда, через сигналослоты?

и ещё такой полуоффтоп, эта вся тема вознилка с того что я собирался обрабатывать сокет в потоке по классике, в этом есть смысл в кутэ или там через сигналы - слоты самого сокета проще будет?
« Последнее редактирование: Январь 13, 2010, 21:48 от foxexe » Записан
Dendy
Гость
« Ответ #13 : Январь 13, 2010, 21:53 »

От сигналов-слотов в потоке вы всё равно не денетесь, другое дело что они будут выполняться в том же потоке, в котором этот сокет существует. По поводу вызова QTextEdit::append() - нужно как-то вот так выкрутиться, чтобы вызывать этот метод из главного потока. Например, вызвать в главном потоке слот с помощью Qt::BlockingQueuedConnection.
Записан
foxexe
Гость
« Ответ #14 : Январь 13, 2010, 22:01 »

всё раскручивается, это значит изначально неправильно, сокет то в главном потоке создаётся, а это возможно подобные проблемы. те либо его сразу в новый потом и там уже чё-нить делать, либо как-нить по другому, со стороны сервера это ещё куда ни шло такой расклад, но клиет с одним сокетом глуповато, да. Ну лан спасибо за информацию про блокед коннекш тоже почитаю, вообщем буду аккуратней с потоками, я просто до этого работал с ними на более банальном уровне только.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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