• QT多线程学习


    一、想要使用Qthread必须先创建,继承Qthread的类。

     1 #ifndef THREADTEST_H
     2 #define THREADTEST_H
     3 
     4 #include <QThread>
     5 #include <QMutex>
     6 
     7 class ThreadTest : public QThread
     8 {
     9 public:
    10     ThreadTest();
    11     ~ThreadTest();
    12 
    13     void setMessage(const QString &message);
    14     void stop();
    15 
    16 protected:
    17     void run() Q_DECL_OVERRIDE;
    18 
    19 
    20 private:
    21     QString messageStr;
    22     volatile bool stopped;
    23     QMutex mutex;
    24     bool quit;
    25 
    26 };
    27 
    28 #endif // THREADTEST_H
    Qthread继承

    创建的类中有void run()函数和void stop()。

    当调用start()函数时,会接着调用run函数。

    二、Mutex互斥锁

    可以用mutex.lock()上锁,mutex.unlock()解锁。用以保护资源。

    然后可以用简化的方式使用QmutexLocker lock(&mutex),函数中部分结束后自动释放。

    还有QReadWriteLock来替换mutex。lock.lockForRead(),lock.lockForWrite()

    三、信号量

    QSemaphore semaphore(1);

    semaphore.acquire();

    semaphore.release();

    信号量和互斥量的区别在于信号量可以设置初值。

    四、在生产和消费中的应用。

    freeSpace.acquire();

    freeSpace.realease();

    usedSpace.acquire();

    usedSpcae.release();

    五、QWaitCondition

    QWaitCondition允许一个线程在满足一定的条件下触发其他多个线程。可以和QMutex一起使用达到精确控制。

    不同的消息就要用到不同的QWaitCondition,传入的参数必须是锁定的mutex。

    #include <iostream>
    #include <QtCore>
    
    using namespace std;
    
    const int DataSize = 200;
    const int BufferSize = 10;
    int buffer[BufferSize];
    int usedSpace = 0;
    
    QMutex mutex;
    QWaitCondition bufferIsNotEmpty;
    QWaitCondition bufferIsNotFull;
    
    class Producer : public QThread
    {
        void run();
    };
    
    void Producer::run()
    {
        for(int i =0;i<DataSize;i++)
        {
            mutex.lock();
            if(usedSpace == BufferSize)
                bufferIsNotFull.wait(&mutex);
            buffer[i%BufferSize] = i;
            std::cerr<<"P";
            usedSpace++;
            bufferIsNotEmpty.wakeAll();
            mutex.unlock();
        }
    }
    
    class Consumer : public QThread
    {
        void run();
    };
    
    void Consumer::run()
    {
        for(int i =0;i<DataSize;i++)
        {
            mutex.lock();
            if(usedSpace == 0)
                bufferIsNotEmpty.wait(&mutex);
            usedSpace--;
            std::cerr<<buffer[i%BufferSize]<<" ";
            bufferIsNotFull.wakeAll();
            mutex.unlock();
        }
    }
    
    int main()
    {
        Producer producer;
        Consumer consumer;
        producer.start();
        consumer.start();
        producer.wait();
        consumer.wait();
        return 0;
    }
    QWaitCondition

     用QSemaphore也可以实现

    const int DataSize = 100000;
    const int BufferSize = 8192;
    char buffer[BufferSize];
    QSemaphore freeBytes(BufferSize);
    QSemaphore usedBytes;
    class Producer : public QThread
    {
    public:
         void run();
    };
    void Producer::run()
    {
         qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
         for (int i = 0; i < DataSize; ++i) {
             freeBytes.acquire();
             buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4];
             usedBytes.release();
         }
    }
    class Consumer : public QThread
    {
    public:
         void run();
    };
    void Consumer::run()
    {
         for (int i = 0; i < DataSize; ++i) {
             usedBytes.acquire();
             fprintf(stderr, "%c", buffer[i % BufferSize]);
             freeBytes.release();
         }
         fprintf(stderr, "
    ");
    }
    int main(int argc, char *argv[])
    {
         QCoreApplication app(argc, argv);
         Producer producer;
         Consumer consumer;
         producer.start();
         consumer.start();
         producer.wait();
         consumer.wait();
         return 0;
    }
    Qsemaphore

    六、而Main和次线程通信

    要是实现这个功能可以用信号和槽机制

    在主界面中运行创建一个Thread *mythread指针,然后mythread->start();不会出错。

    无欲速,无见小利。欲速,则不达;见小利,则大事不成。
  • 相关阅读:
    PAT Basic 1023 组个最小数 (20 分)
    PAT Advanced 1048 Find Coins (25 分)
    PAT Basic 1005 继续(3n+1)猜想 (25 分)
    PAT Advanced 1050 String Subtraction (20 分)
    PAT Advanced 1041 Be Unique (20 分)
    PAT Basic 1047 编程团体赛 (20 分)
    SpringSecurity整合SpringBoot
    给正在运行的Docker容器动态绑定卷组
    linux 中格式化json字符串
    docker/kubernetes国内源/镜像源解决方式
  • 原文地址:https://www.cnblogs.com/ch122633/p/7496748.html
Copyright © 2020-2023  润新知