C++ (Qt)class Thread: public QThread{public: ~Thread () { ::std::cout << "Deleted" << ::std::endl; } virtual void run () { ::std::cout << "Before exec" << ::std::endl; exec(); ::std::cout << "After exec" << ::std::endl; }}; int main ( int argc, char ** argv ){ QCoreApplication app( argc, argv ); QThread * thread = new Thread; thread->moveToThread( thread ); thread->start(); thread->deleteLater(); thread->quit(); return app.exec();}
Before execAfter exec
Before execDeletedQThread: Destroyed while thread is still runningAfter exec
C++ (Qt)thread->quit();thread->wait();delete thread;
QThread: Destroyed while thread is still running
C++ (Qt)#include <QCoreApplication>#include <QThread>#include <QTimer>#include <QDebug> class Worker : public QObject { Q_OBJECTpublic: Worker(QObject *parent = 0) : QObject(parent), mTimer(0) {} ~Worker() { qDebug() << Q_FUNC_INFO; } Q_INVOKABLE void start() { // для того, что бы создать таймер в контексте потока, в который перемещён // воркер, используем QMetaObject::invokeMethod if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection); return; } mTimer = new QTimer(this); connect(mTimer, &QTimer::timeout, this, &Worker::onTimeout); mTimer->start(1000); } signals: void timeout(); private: void onTimeout() { qDebug() << "worker" << QThread::currentThreadId(); emit timeout(); } private: QTimer *mTimer; }; class Test : public QObject{ Q_OBJECTpublic: Test(QObject *parent = 0) : QObject(parent), mWorker(new Worker()) { connect(mWorker, &Worker::timeout, this, &Test::onTimeout, Qt::QueuedConnection); } ~Test() { // планируем удаление воркера mWorker->deleteLater(); if (mThread.isRunning()) { // рубим поток mThread.quit(); // даём время уничтожится воркеру mThread.wait(); } qDebug() << Q_FUNC_INFO; } void start() { // перемещаем воркер в отдельный поток mWorker->moveToThread(&mThread); // стратуем поток mThread.start(); // и воркер mWorker->start(); // планируем через 5 секунд выход из тестового приложения QTimer::singleShot(5000, this, &Test::onQuitTimeout); } void onTimeout() { qDebug() << "test" << QThread::currentThreadId(); } void onQuitTimeout() { qApp->quit(); } private: QThread mThread; Worker *mWorker; }; int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); Test t; t.start(); return a.exec();} #include "main.moc"
C++ (Qt)while(!asleep()) sheep++;
C++ (Qt)mWorker->deleteLater();
C++ (Qt)bool QThread::wait(unsigned long time){ Q_D(QThread); QMutexLocker locker(&d->mutex); if (d->thread_id == pthread_self()) { qWarning("QThread::wait: Thread tried to wait on itself"); return false; } if (d->finished || !d->running) return true; while (d->running) { if (!d->thread_done.wait(locker.mutex(), time)) return false; } return true;}
C++ (Qt)MyThread thread;thread.moveToThread( &thread );thread.start();...thread.quit();thread.wait();
C++ (Qt)class MyThread : public QThread{public: MyThread () { moveToThread( this ); } ~MyThread () { quit(); wait(); }...}; MyThread thread;thread.start();...