3.5 線程池基本用法
#include <QCoreApplication>
#include <QDebug>
#include <QRunnable>
#include <QThread>
#include <QThreadPool>
class MyRun : public QRunnable
{
public:
MyRun()
{
}
~MyRun()
{
}
public:
void run()
{
int i = 3;
while (i)
{
i--;
qDebug() << "thread start:" << QThread::currentThreadId();
QThread::msleep(500);
}
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "Main:" << QThread::currentThreadId();
QThreadPool m;
m.setMaxThreadCount(2);
m.setExpiryTimeout(-1);
MyRun *run = new MyRun;
if (!run->autoDelete())
{
qDebug() << "QRunnable's autoDelete default value is not true";
run->setAutoDelete(true);
}
qDebug() << m.maxThreadCount() << m.expiryTimeout();
qDebug() << m.activeThreadCount();
m.start(run);
qDebug() << m.activeThreadCount();
m.waitForDone();
qDebug() << m.activeThreadCount();
return 0;
}
3.6 線程池内的子線程發信号
需要派生QObject!
class MyThread_draw2D_SectionChart : public QObject, public QRunnable
{
Q_OBJECT
public:
MyThread_draw2D_SectionChart(int frameNo) :
m_iFrameNo(frameNo)
{
}
virtual ~MyThread_draw2D_SectionChart()
{
qDebug() << "~MyThread";
}
public:
virtual void run();
private:
int m_iFrameNo;
signals:
void sig_updateUI_SectionChart(int frameNo);
};
4、子線程發信号給主線程,更新UI
通過信号槽的機制可以實作,子線程發信号給主線程即可。不會阻塞。
啟動線程
m_future_2d_SectionChart = QtConcurrent::run(this, &FormContent::thread_draw2D_SectionChart);
子線程
void FormContent::thread_draw2D_SectionChart(void)//繪制2D截面圖
{
qDebug() << "sub thread id:" << QThread::currentThreadId();
connect(this, SIGNAL(sig_updateUI_SectionChart()), this, SLOT(slot_updateUI_SectionChart()));
while (true)
//去主線程更新UI
emit sig_updateUI_SectionChart();
}
主線程
void FormContent::slot_updateUI_SectionChart(void)//更新2D截面圖
qDebug() << "main thread id:" << QThread::currentThreadId();
m_pFormTimeline->updateSectionChart();
5、資料保護,加鎖解鎖
QMutex 提供互相排斥的鎖,或互斥量;有遞歸和非遞歸之分;
QMutexLocker 是一個輔助類,自動對 QMutex 加鎖與解鎖;
QReadWriterLock 提供了一個可以同時讀操作的鎖;有遞歸和非遞歸之分;
QReadLocker與QWriteLocker 自動對QReadWriteLock 加鎖與解鎖;
QSemaphore 提供了一個整型信号量,是互斥量的泛化;
QWaitCondition 提供了一種方法,使得線程可以在被另外線程喚醒之前一直休眠。
https://doc.qt.io/qt-5/qmutex.html https://doc.qt.io/qt-5/qmutexlocker.html https://doc.qt.io/qt-5/qreadlocker.html https://doc.qt.io/qt-5/qwritelocker.html https://doc.qt.io/qt-5/qreadwritelock.html https://doc.qt.io/qt-5/qsemaphore.html https://blog.csdn.net/guoyufeng25/article/details/1031052446、線程優先級
Qthread的優先級屬性:Priority訓示系統如何排程線程。
QThread::IdlePriority 0
scheduled only when no other threads are running.
QThread::LowestPriority 1
scheduled less often than LowPriority.
QThread::LowPriority 2
scheduled less often than NormalPriority.
QThread::NormalPriority 3
the default priority of the operating system.
QThread::HighPriority 4
scheduled more often than NormalPriority.
QThread::HighestPriority 5
scheduled more often than HighPriority.
QThread::TimeCriticalPriority 6
scheduled as often as possible.
QThread::InheritPriority 7
use the same priority as the creating thread. This is the default.
x、多線程的進階應用
TCP Client/TCP Server
https://sourceforge.net/projects/threader-qt/ https://sourceforge.net/p/threader-qt/svn/HEAD/tree/future/promise【推薦】
https://github.com/mhogomchungu/tasksy、參考文獻
https://github.com/czyt1988/czyBlog/tree/master/tech/QtThread https://www.cnblogs.com/xia-weiwen/p/10306089.html https://github.com/Xia-Weiwen/CopyFile