Typically, an application performs an operation in a thread. However, the user interface is often frozen when a time-consuming operation is invoked (for example, a CPU-intensive operation such as large-volume I/O or a large number of matrix transformations). Using multithreading can solve this problem.
Multithreading has several advantages:
1. Improve application response speed. This is particularly important for the development of graphical interface programs, when an operation takes a long time, the entire system will wait for this operation, the program can not respond to keyboard, mouse, menu and other operations, and the use of multithreading technology can be long-time operation on a new thread, to avoid the above problems.
2. Make multi-CPU systems more efficient. When the current number of threads is not greater than the number of CPUs, the operating system can schedule different threads to run on different CPUs.
3. Improve the program structure. A long and complex process can be considered as a separate or semi-independent running part, which facilitates the understanding and maintenance of the code.
There are several features of multi-threaded threads:
1. The behavior of multithreaded programs cannot be expected, and each time a program is executed, the results may vary.
2. The order of execution of multithreading is not guaranteed, and it is related to factors such as scheduling policy and thread priority of the operating system.
3. Multi-threaded switching can occur at any time, any location.
4. Multithreading is highly sensitive to code, and subtle changes to the code can produce unexpected results.
Based on these characteristics, developers must control the threads in order to use them effectively.
Example:
Start button
void Widget::on_pushbutton_clicked ()
{
if (timer->isactive ()!=true)
Timer->start (100);
Qthread::sleep (5);
}
The timer is described in the previous example. As seen in the above statement, Timer->start (100) starts the timer and then lets the thread hibernate 5ms. The result is that the window is not responding and the card is dead directly.
Parsing: Because the previous examples are all single-job. Sleep even 5MS,CPU will handle other homework. It is also because all the interfaces in Qt are in the UI line approached (also known as the main thread, that is, executing the qapplication::exec () threads), executing time-consuming operations (such as that loop) in this thread, which blocks the UI thread, thus causing the interface to stop responding.
Then use the thread to try, the main window to achieve the constant accumulation of timers, the sleep is placed in the thread. Such as: Sleep in the thread (50), the thread sleeps 50ms, and the main window of the thread's timer will also be close to 50ms. Is it possible to show that the thread of the window is at the same time as the child thread?
The creation and use of QT threads:
Parse: Create a new C + + class (no designer required), mythread as the thread class. At this point, you will modify the base class of the thread class (changed from Qwidget to Qthread). The threading function used is a virtual function in the Qthread class (see).
Simply put, create a thread class, and all of the work in the thread is written in that class. Interface: Emit XXX. The signal emitted is the interface of the class. Easy to use for other classes or Windows.
Thread class:
Class Mythread:public Qthread
{
Protected
void run ();
Signals:
void Mysignal ();
}
To override a thread-handling function:
void Mythread::run ()
{
Qthread::sleep (50);
Emit mysignal ();
Qdebug () << "Child thread ID:" <<qthread::currentthreadid ();
}
Main window class, start timer, and turn on thread
void Widget::on_pushbutton_clicked ()
{
if (timer->isactive ()!=true)
Timer->start (1000);
Mythread.start ();
Qdebug () << "main thread ID:" <<qthread::currentthreadid ();
}
Accept a signal from a thread
Connect (&mythread,&mythread::mysignal,
[=] ()
{
Qdebug () << "over";
Timer->stop ();
}
The ID of the main thread is different from the child thread's ID, and the child thread sleep time is similar to the main thread run time:
Child thread shutdown issues
When we close the window or close the main thread, but the child threads are still running. As below, our timer has been paused, but the child thread also executes.
Workaround: Manually invoke the slot function of the Qthread class.
Note: It is recommended to use Quit (), which waits for a child thread to perform a full operation before shutting down. The Terminate () closes the thread immediately after the call, regardless of the thread's subsequent operation.
When the window closes, the child thread is closed
Connect (this,&qwidget::d estroyed,
[=] ()
{
Mythread.quit ();
Mythread.wait ();
}
);
Source:
Mythread.h
#ifndef Mythread_h
#define Mythread_h
#include <QWidget>
#include <QThread>
Class Mythread:public Qthread
{
Q_object
Public
Explicit MyThread (Qobject *parent = 0);
Protected
void run (); Thread-handling functions
Signals:
void Mysignal (); Thread signal
Public Slots:
};
#endif//Mythread_h
Mythread.cpp
#include "Mythread.h"
#include <QDebug>
Mythread::mythread (Qobject *parent):
Qthread (parent)
{
}
Overriding a thread handler function
void Mythread::run ()
{
Qthread::sleep (50);
Emit mysignal (); The thread completes the operation and sends a signal
Qdebug () << "Child thread ID:" <<qthread::currentthreadid ();
}
Widget.h
#ifndef Widget_h
#define Widget_h
#include <QWidget>
#include <QTimer>
#include "Mythread.h"
Namespace Ui {
Class Widget;
}
Class Widget:public Qwidget
{
Q_object
Public
Explicit Widget (Qwidget *parent = 0);
~widget ();
Private Slots:
void on_pushbutton_clicked (); Start button
void on_pushbutton_2_clicked (); Pause button
Private
Ui::widget *ui;
Qtimer *timer; Timer Object
MyThread MyThread; Thread Object
};
#endif//Widget_h
Widget.cpp
#include "Widget.h"
#include "Ui_widget.h"
#include <QThread>
#include <QDebug>
Widget::widget (Qwidget *parent):
Qwidget (parent),
UI (New Ui::widget)
{
UI->SETUPUI (this);
Timer=new Qtimer (this);
Timer slot function
Connect (Timer,&qtimer::timeout,
[=] ()
{
static int num=0;
Ui->lcdnumber->display (num);
num++;
}
);
Thread Signal slot function
Connect (&mythread,&mythread::mysignal,
[=] ()
{
Qdebug () << "over";
Timer->stop ();
}
);
Close the window and close the child thread
Connect (this,&qwidget::d estroyed,
[=] ()
{
Mythread.quit ();
Mythread.wait ();
}
);
}
Widget::~widget ()
{
Delete UI;
}
Start button, start timer and thread
void Widget::on_pushbutton_clicked ()
{
if (timer->isactive ()!=true)
{
Timer->start (1000);
}
Mythread.start ();
Qdebug () << "main thread ID:" <<qthread::currentthreadid ();
}
void Widget::on_pushbutton_2_clicked ()
{
if (timer->isactive () ==true)
{
Timer->stop ();
}
}
28 Initial Knowledge Thread