天天看點

Qt5多線程/線程池技術集錦(2)

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/103105244

6、線程優先級

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/tasks

y、參考文獻

https://github.com/czyt1988/czyBlog/tree/master/tech/QtThread https://www.cnblogs.com/xia-weiwen/p/10306089.html https://github.com/Xia-Weiwen/CopyFile