QT线程之间通信的方法
1.信号槽
这是QT特有的方法。通过信号携带参数进行传值,槽函数接收信号的参数即可跨线程通信。
2.动态属性
同属于QT的特性,元对象系统三大功能之一。在运行过程中可以动态为一个继承自QObject的对象进行创建属性并赋值。
在主线程中:
MyObject obj;
// 设置属性
obj.setProperty(“myProperty”, QVariant(42));
// 获取属性
在子线程中:
QVariant value =property(“myProperty”);
3.指针
通过传递指针的方式也是可以达到要求的。
class dataPoint{
int a;
double b;
string d;
}
然后在使用的时候创建一个这个类的指针,修改里面的数据,如果想传递数据的时候直接传递指针就好了。因为指针保存的数据是对象的地址,所以传递的数据量只有几个字节。
4.共享内存(互斥锁)
主线程可以设计一个共享变量在多个线程之间共享。该方法需要借助互斥锁和条件变量。
使用方法
这里使用生产者-消费者模式。
所谓生产者-消费者就是要先生产数据然后放到缓冲区里面,消费者才能够使用。鸡蛋(数据)由生产者(鸡)生产,之后放到篮子(缓冲区),消费者(顾客)就可以挑选购买了。
生产鸡蛋:
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
class Producer : public QThread {
Q_OBJECT
public:
Producer(QMutex *mutex, QWaitCondition *condition, QList<int> *buffer)
: mutex(mutex), condition(condition), buffer(buffer) {}
void run() override {
for (int i = 0; i < 10; ++i) {
mutex->lock();
buffer->append(i);
qDebug() << "Produced: " << i;
condition->wakeAll();
mutex->unlock();
msleep(1000);
}
}
private:
QMutex *mutex;
QWaitCondition *condition;
QList<int> *buffer;
};
顾客:
class Consumer : public QThread {
Q_OBJECT
public:
Consumer(QMutex *mutex, QWaitCondition *condition, QList<int> *buffer)
: mutex(mutex), condition(condition), buffer(buffer) {}
void run() override {
while (true) {
mutex->lock();
while (buffer->isEmpty()) {
condition->wait(mutex);
}
int value = buffer->takeFirst();
qDebug() << "Consumed: " << value;
mutex->unlock();
}
}
private:
QMutex *mutex;
QWaitCondition *condition;
QList<int> *buffer;
};
运行:
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
QMutex mutex;
QWaitCondition condition;
QList<int> buffer;
Producer producer(&mutex, &condition, &buffer);
Consumer consumer(&mutex, &condition, &buffer);
producer.start();
consumer.start();
return app.exec();
}
首先写了一个互斥锁和一个条件变量,在生产鸡蛋的时候,每次生产都使用同一把锁进行加锁。
条件变量是为了通知消费者这里有鸡蛋可以买。
购买流程:
从前有一个商人,他只有一只鸡。他很宝贝这只鸡。每次只许生一个蛋。
他每次在鸡生蛋的时候就会上锁不让其他顾客进来(由于这里只有两个线程,一个是生蛋,一个是购买,所以给生蛋上锁,购买线程就是禁止了,反之亦然)。
每当下了一个蛋,就解开锁并让鸡歇会,不让它继续。然后在门口放了个有蛋售卖的牌子。
而顾客呢,也是在一开始就等着鸡蛋呢,好不容易可以进来,然后也上了锁不许鸡下蛋,即便鸡已经醒了。他先检查一下是否有鸡蛋,如果有就买,买完后才解开锁。
在这个时候,鸡和顾客都有抢这个锁的权力。但是现在已经没有鸡蛋了,顾客有锁也没用,即便他很急还需要更多的鸡蛋并且不希望其他顾客抢到买鸡蛋的权力,但鸡是只要有人强锁它就不下蛋,商人只能乖乖让出锁先让鸡下蛋(condition->wait(mutex))。