1. Thread starts
In Qt, there are generally two ways to start the child thread:
a, define the worker class:
The worker inherits QThread, rewrites the run function, instantiates the worker in the main thread, puts the time-consuming work into the worker's run function, and completes it. After it is finished, send a signal to the main thread and passes the parameters.
Note: In this worker instance, only the run function is executed in the child thread, and other functions of the worker are executed in the main thread.
If the child thread has started and the run function has not been run yet, start again. At this time, the child thread will not have any operations, the run function will not be called again, and the run function will continue to be executed.
b, define the worker class:
The worker inherits Qobject, completes time-consuming operations in the worker, and #include "" comes in in the main thread. Then, several child threads QThread are New in the main thread, and use the moveToThread() function to transfer the worker into the child thread, for example:
pWorker = new Worker; pThread1 = new QThread; pWorker->moveToThread(pThread1)
After that, according to the needs, see when the child thread will be opened: pThread1->start();
If the thread is already running, you will not perform any processing by repeatedly calling start.
2. Thread closing
For the above class a, if the child threads opened in run, if exec() is not called in run, using quit() and exit(), it cannot break out of the loop in run and terminate the child thread. No effect will occur, and QThread will not exit the run halfway through the running just because you call the quit() function.
However, using QThread's terminate() method can immediately end the child thread, but this function has very unstable factors and is not recommended. So how to safely terminate a thread?
The easiest way is to add a bool variable and terminate it by modifying the bool variable through the main thread, but this may cause access violations and need to be locked.
void myThread::run() { int count = 0; m_isCanRun = true;//The mark can run QString str = QString("%1->%2,thread id:%3").arg(__FILE__).arg(__FUNCTION__) .arg((unsigned int)QThread::currentThreadId()); emit message(str); while(1) { sleep(1); ++count; doSomething(); if(m_runCount == count) { break; } { QMutexLocker locker(&m_lock);// Add lock here to prevent access violations if(!m_isCanRun)//Display whether it can run every time, and if it doesn't work, exit the loop { return; } } } }
Therefore, after encountering the judgment of m_isCanRun in the run function of the child thread, the run function will be exited. The function inheriting QThread will be regarded as the thread completion after running the run function and will transmit a finish signal.
Try not to delete the child thread pointer, as this is not safe. The QObject::deleteLater() method is generally bound.
connect(pThread,&QThread::finished ,thread,&QObject::deleteLater);
After the thread is finished, deleteLater is called to destroy the allocated memory.
For the above class b, after Qt4.8, it is best to implement the Qt multithreading method through QObject, and the interaction with the thread is connected through signals and slots (actually through events).
The method of inheriting QObject multithreading is very simple to create threads. Just let the QThread start function run, but you need to pay attention to the method of destroying threads: After the thread is created, the destruction of this QObject should not be carried out in the main thread, but is safely destroyed through the deleteLater slot. Therefore, the method of inheriting QObject multithreading has several slot functions when creating:
- One is the QThread finished signal docking with the deleteLater of QObject so that after the thread is finished, the multi-threaded class inheriting QObject will be destroyed by itself.
- The other is the finished signal of QThread connects to QThread's own deleteLater. This is not necessary. The following official example does not do this:
class Worker : public QObject { Q_OBJECT public slots: void doWork(const QString ¶meter) { QString result; /* ... here is the expensive or blocking operation ... */ emit resultReady(result); } signals: void resultReady(const QString &result); }; class Controller : public QObject { Q_OBJECT QThread workerThread; public: Controller() { Worker *worker = new Worker; worker->moveToThread(&workerThread); connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); connect(this, &Controller::operate, worker, &Worker::doWork); connect(worker, &Worker::resultReady, this, &Controller::handleResults); (); } ~Controller() { (); (); } public slots: void handleResults(const QString &); signals: void operate(const QString &); };
The method of creating multithreading using QObject is as follows:
- Write a class that inherits QObject and declare the entry function that requires complex and time-consuming logic as a slot function
- This class comes out in the old thread new, and cannot set any parent object for it
- At the same time, a QThread object is declared. In the official example, QThread is not new, so it needs to be called during destruction - - QThread::wait(). If it is heap allocation, you can use deleteLater to make the thread commit suicide
- Transfer obj to a new thread through moveToThread method, and the object is already in the thread.
- Connect the finished signal of the thread to the deleteLater slot of the object. This signal slot must be connected, otherwise memory leaks
- Normally connect other signals and slots (call moveToThread before connecting the signal slot, and you do not need to process the fifth parameter of the connect, otherwise the display statement will be connected with Qt::QueuedConnection)
- After initialization, call 'QThread::start()' to start the thread
- After the logic is over, call QThread::quit to exit the thread's event loop
This is the end of this article about the implementation of Qt thread QThread activation and safe exit. For more related Qt QThread activation and exit content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!