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


上一篇:44_类加载器及其委托机制的深入分析


下一篇:Python工程师需要掌握的面试题