Название: QThread генерирует ошибку до начала выполнения Отправлено: foxexe от Январь 13, 2010, 19:04 Я совсем уже опустил руки, создаю классический каркас для треда
Код: class MyThread: public QThread запуская такой тред в различных местах программы получаются разные Debugger error со страшными словами типа ASSET и прочее, ну иногда можно добиться вывода такой ошибки QThread: Destroyed while thread is still running хотя тред то ещё даже не исполнил не одной строчки из своей функции. Я конечно очень криво написал, но я честно вообще не понимаю что происходит. у меня такая странная догадочка что тред уничтожается или как-нить неправильно инициаллизируется, всё это происходит при вызове start(); даже запуск такого треда в фукции main даёт ошибки, но уже что QWidget должет создаваться только в gui треде. Qt 4.4.3 VS2008 Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: Dendy от Январь 13, 2010, 19:07 Покажите как вы создаёте экземпляр этого потока.
Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: foxexe от Январь 13, 2010, 19:11 пробовал 2 варианта
Код: MyThread a; Код: MyThread *a=new MyThread(); если создать пустой проект то такие штуки работают. даже добавид CONFIG += thread хотя это я понимаю не особо важно Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: Dendy от Январь 13, 2010, 19:25 Подозреваю, что тред создаётся и запускает run() в другом потоке раньше, чем в вызывающем доходит до конца области видимости. Потом вызывается деструктор потока, в то время как его клавный цикл exec() не был остановлен. По умолчанию ~QThread() его сам не останавливает, поскольку это не гарантирует, что run() завершился корректно - ведь после exec() может быть ещё клиентский код. Вот он и ругается, что поток был прерван с возможными ошибками. Не было бы exec() - всё было бы так же печально, но с отличием, что ~QThread() не смог бы определить, выполняется ли ещё поток или нет. Отловить поведение собственного потока можно только самостоятельно в деструкторе, отправив циклу событий quit() и подождав, пока поток завершится с помощью wait().
Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: foxexe от Январь 13, 2010, 19:47 Да спасибо, это кстати очень классная догадка, я бы недодумался , но я там всё же создавал по ссылке изначально, на самом деле он ругается что я пользуюсь объектом из другого потока что-ли. я вообще не особо понимаю в чём проблема, просто помню была такая ошибочка, вылезала, и правда убрал все вызовы лишние работает, только вот как же теперь обратиться к объектам созданным в главном потоке
Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: Dendy от Январь 13, 2010, 19:52 Непонятно откуда и к чему вы хотите обратиться.
Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: foxexe от Январь 13, 2010, 20:08 да я кстати щас вот думал как переформулировать и тут такое дело, что в основном потоке создаётся класс Engine, который собственно движок. и вот я в его конструкторе(в отлажочных целях) создаю поток, и обращаюсь к Engine по глобальной ссылке.
main.cpp Код: MyEngine *Engine Код: extern MyEngine * Engine у меня сейчас спутанность сознания какая-то и я вобщем вижу что есть в этом кривизна, но в чём именно не пойму. получается что мне надо общать с этим Engine через сигнал-слоты? Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: Dendy от Январь 13, 2010, 20:36 Можно общаться как и сейчас, только гарантировать:
1) Что обьект Engine будет существовать во время обращения к нему. 2) Потокобезопастность метода MyEngine::method(). Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: foxexe от Январь 13, 2010, 20:56 ну Engine да создан, но method() просто запускает QTextEdit::append() мне не кажется что это настолько потоконебезопасно, я попробую попозже там мютексы поставить, но что-то мне кажется не в этом то дело.
Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: Dendy от Январь 13, 2010, 21:00 Этот метод не может быть потокобезопастрым, поскольку QTextEdit::append() уже не reentrant. Его можно вызывать только из главного потока.
Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: foxexe от Январь 13, 2010, 21:19 так вот гда собака то зарыта!!! ес
а можно узнать что-же происходит если я вызываю её из другого потока? Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: Dendy от Январь 13, 2010, 21:33 Race Condition стало быть с непредсказуемыми последствиями.
Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: foxexe от Январь 13, 2010, 21:45 Пока не забыл, очень очень очень огромное спасибо, помог и заставил меня думать.
точно точно, отсюда и постоянно разные ошибки, в разных файлах в разных местах я так понимаю что гонка может произойти при условии что остальные потоки не запускают QTextEdit::append(), внутреняя архитектура тоесть там что-то там-то. А всё-таки как мне обращаться в этим method() тогда, через сигналослоты? и ещё такой полуоффтоп, эта вся тема вознилка с того что я собирался обрабатывать сокет в потоке по классике, в этом есть смысл в кутэ или там через сигналы - слоты самого сокета проще будет? Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: Dendy от Январь 13, 2010, 21:53 От сигналов-слотов в потоке вы всё равно не денетесь, другое дело что они будут выполняться в том же потоке, в котором этот сокет существует. По поводу вызова QTextEdit::append() - нужно как-то вот так выкрутиться, чтобы вызывать этот метод из главного потока. Например, вызвать в главном потоке слот с помощью Qt::BlockingQueuedConnection.
Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: foxexe от Январь 13, 2010, 22:01 всё раскручивается, это значит изначально неправильно, сокет то в главном потоке создаётся, а это возможно подобные проблемы. те либо его сразу в новый потом и там уже чё-нить делать, либо как-нить по другому, со стороны сервера это ещё куда ни шло такой расклад, но клиет с одним сокетом глуповато, да. Ну лан спасибо за информацию про блокед коннекш тоже почитаю, вообщем буду аккуратней с потоками, я просто до этого работал с ними на более банальном уровне только.
Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: Dendy от Январь 13, 2010, 22:04 Принадлежность к потоку обьектов вообще и сокета в частности определяется тем, в что этом потоке будут дёргаться виртуальный метод QObject::event(). Создавайте сокет внутри своего run() - это сделает его принадлежащим потоку, которому этот run() принадлежит.
Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: foxexe от Январь 13, 2010, 22:18 ну да значит я всё правильно думаю, спасибо огромное
смотря на тему становится даже немного стыдно) Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: Dendy от Январь 13, 2010, 22:24 Да ладно, работа с потоками - то ещё болото. И никакая теория не будет полноценной, пока сам в нём не искупаешься.
Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: BlackTass от Январь 13, 2010, 22:28 можно создавать и в конструкторе, главное только потом перенести с помощью метода moveToThread() (метод класса QObject). Вызывать его надо из того потока, где был создан объект. И не забудьте объект самого потока перенести в этот поток.
Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: Dendy от Январь 13, 2010, 22:36 И не забудьте объект самого потока перенести в этот поток. Сильно сомнительный подход, от которого больше проблем. Лучше так не делать. Как минимум события потока, а следовательно и слоты, не будут обрабатываться до и после exec(). Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: foxexe от Январь 13, 2010, 22:40 Да ладно, работа с потоками - то ещё болото. И никакая теория не будет полноценной, пока сам в нём не искупаешься. да это я абсолютно согласен. Мне хватило даже институтских прог сначала винда, потом соляра, и там эти вещи побезопасней для потоков сделаны вроде.можно создавать и в конструкторе, главное только потом перенести с помощью метода moveToThread() (метод класса QObject). Вызывать его надо из того потока, где был создан объект. И не забудьте объект самого потока перенести в этот поток. очень хорошо подмечено, я и забыл про moveToThread(). однако это не решает моей архитектурной проблемы обработки приёма и отправки в разных потоках. ладно буду думать что тут делать. А зачем мне переносить объект потока к себе в поток? Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: BlackTass от Январь 13, 2010, 22:45 Сильно сомнительный подход, от которого больше проблем. Лучше так не делать. Как минимум события потока, а следовательно и слоты, не будут обрабатываться до и после exec(). ну после exec() в большинстве случаев наступает смерть потока. Зато такой подход позволяет отделить обработку слотов объекта потока от потока-родителя (примерно в половине случаев это гуй-поток), что соответственно разгружает его. Хотя вы правы, я погорячился советовать это делать всегда. Нужно понимать к чему приведет такое и для чего это нужно. Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: Dendy от Январь 13, 2010, 22:55 А зачем мне переносить объект потока к себе в поток? Как правило в run() создаётся нечто, что будет там жить и ловить события. Поток засовывают сам в себя когда лень создавать новый класс-обработчик, наследник QObject. Однако такой подход рвёт всё управление событиями/слотами экземпляром потока извне и влечёт ошибки на пустом месте. Технически никакого преимущества, кроме того, что два класса смешаны в один. И да, фильтр событий тоже не будет работать между потоками, зачем так сделано в Qt мне непонять. Название: Re: QThread генерирует ошибку до начала выполнения Отправлено: BlackTass от Январь 13, 2010, 23:59 Однако такой подход рвёт всё управление событиями/слотами экземпляром потока извне и влечёт ошибки на пустом месте. Технически никакого преимущества, кроме того, что два класса смешаны в один. Ну по сути да, удобство только в исключении класса. Ну и в отстутствии пробросов сигнал-сигнал-слот для необходимых снаружи слотов, которые должны испольняться в отдельном евентлупе |