假设有一个多线程程序,其中一个线程是生产者,另外两个线程是消费者。生产者会不断地生成数据,并将其放入一个共享的缓冲区中;而消费者则会从缓冲区中取出数据进行处理。
在这种情况下,我们需要使用信号量来同步生产者和消费者之间的操作。具体实现如下:
#include <QtCore/QCoreApplication>
#include <QtCore/QSemaphore>
#include <QtCore/QThread>
const int BUFFER_SIZE = 10; // 缓冲区大小
class Producer : public QThread {
public:
Producer(QSemaphore* freeSpace, QSemaphore* usedSpace) :
freeSpace(freeSpace), usedSpace(usedSpace) {}
protected:
void run() override {
for (int i = 0; i < 100; ++i) {
freeSpace->acquire(); // 等待空闲空间
buffer[i % BUFFER_SIZE] = i; // 将数据存入缓冲区
usedSpace->release(); // 发送已用空间信号
msleep(500); // 模拟生成数据的时间
}
}
private:
QSemaphore* freeSpace;
QSemaphore* usedSpace;
int buffer[BUFFER_SIZE];
};
class Consumer : public QThread {
public:
Consumer(QSemaphore* freeSpace, QSemaphore* usedSpace) :
freeSpace(freeSpace), usedSpace(usedSpace) {}
protected:
void run() override {
for (int i = 0; i < 100; ++i) {
usedSpace->acquire(); // 等待已用空间
int data = buffer[i % BUFFER_SIZE]; // 从缓冲区中取出数据
freeSpace->release(); // 发送空闲空间信号
qDebug() << "Consumed:" << data; // 处理数据
msleep(1000); // 模拟处理数据的时间
}
}
private:
QSemaphore* freeSpace;
QSemaphore* usedSpace;
int buffer[BUFFER_SIZE];
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSemaphore freeSpace(BUFFER_SIZE); // 初始状态为缓冲区大小,表示有多少个空闲位置可供使用
QSemaphore usedSpace(0); // 初始状态为0,表示没有任何数据可供消费
Producer producer(&freeSpace, &usedSpace);
Consumer consumer1(&freeSpace, &usedSpace);
Consumer consumer2(&freeSpace, &usedSpace);
producer.start();
consumer1.start();
consumer2.start();
return a.exec();
}
在上述代码中,QSemaphore
被用来实现生产者和消费者之间的同步操作。其中,freeSpace
表示缓冲区中还有多少个空闲位置可以存放数据;usedSpace
表示缓冲区中已经存储了多少个数据。
当生产者线程生成一个新的数据时,它会等待直到缓冲区中有足够的空闲位置才将其存入;而当消费者线程需要获取一个数据时,则必须等待直到缓冲区中有至少一个数据才能取出。这样,就保证了生产者和消费者之间的同步操作。
在实际应用中,我们可以根据具体需求调整信号量的初始值和操作顺序,从而实现不同形式的同步。