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();不会出错。

无欲速,无见小利。欲速,则不达;见小利,则大事不成。
原文地址:https://www.cnblogs.com/ch122633/p/7496748.html