#include <QCoreApplication>
#include <QtCore>
#include <iostream>
#include<QMutex>
const int DataSize = 100;
const int BufferSize = 10;
char buffer[BufferSize];
//定义两个信号量
QSemaphore freeSpace(BufferSize);
QSemaphore usedSpace(0);//刚开始没有生产者写好的数据,所以初始化为0
QMutex lock;
QWaitCondition bufferIsNotFull;
QWaitCondition bufferIsNotEmpty;
QMutex mutex;
int usedSpaceBuffer;
//生产者
class Producer : public QThread
{
public:
void run();
};
//start()调用的就是run()函数。他是一个虚函数,默认情况下调用exec()
//从该函数返回表示线程已经结束
//生产者随机生成一个字母填充进缓冲区buffer
void Producer::run()
{
for (int i = 0; i < DataSize; ++i) {
freeSpace.acquire();//获取“自由的”字节
// buffer[i % BufferSize] = "ACGT"[uint(rand()) % 4];
// lock.lock();
// mutex.lock();
// while(usedSpaceBuffer == BufferSize)
// {
// bufferIsNotFull.wait(&mutex);
// }
std::cerr << "P";
// ++usedSpaceBuffer;
// bufferIsNotEmpty.wakeAll();
// mutex.unlock();
// lock.unlock();
usedSpace.release();//转换为“用过的”(填充过的)字节
}
}
//生产者
class Producer1 : public QThread
{
public:
void run();
};
//start()调用的就是run()函数。他是一个虚函数,默认情况下调用exec()
//从该函数返回表示线程已经结束
//生产者随机生成一个字母填充进缓冲区buffer
void Producer1::run()
{
for (int i = 0; i < DataSize; ++i) {
freeSpace.acquire();//获取“自由的”字节
// buffer[i % BufferSize] = "ACGT"[uint(rand()) % 4];
// lock.lock();
// mutex.lock();
// while(usedSpaceBuffer==BufferSize)
// {
// bufferIsNotFull.wait(&mutex);
// }
std::cerr << "Q";
// bufferIsNotEmpty.wakeAll();
// mutex.unlock();
// lock.unlock();
usedSpace.release();//转换为“用过的”(填充过的)字节
}
}
//生产者
class Producer2 : public QThread
{
public:
void run();
};
//start()调用的就是run()函数。他是一个虚函数,默认情况下调用exec()
//从该函数返回表示线程已经结束
//生产者随机生成一个字母填充进缓冲区buffer
void Producer2::run()
{
for (int i = 0; i < DataSize; ++i) {
freeSpace.acquire();//获取“自由的”字节
// buffer[i % BufferSize] = "ACGT"[uint(rand()) % 4];
// lock.lock();
// mutex.lock();
// while(usedSpaceBuffer==BufferSize)
// {
// bufferIsNotFull.wait(&mutex);
// }
std::cerr << "W";
// bufferIsNotEmpty.wakeAll();
// mutex.unlock();
// lock.unlock();
usedSpace.release();//转换为“用过的”(填充过的)字节
}
}
//消费者
class Consumer : public QThread
{
public:
void run();
};
//将生产者填充进“用过的”字节的字幕读取并输出到控制台
void Consumer::run()
{
for (int i = 0; i < DataSize; ++i) {
usedSpace.acquire();//获取“用过的”资源,如果没有则一直阻塞,直到有资源为止
//std::cerr << buffer[i % BufferSize];
// char Cons = buffer[i % BufferSize];
// lock.lock();
// mutex.lock();
// while(usedSpaceBuffer==0)
// {
// bufferIsNotEmpty.wait(&mutex);
// }
std::cerr <<"c";
// --usedSpaceBuffer;
// mutex.unlock();
// lock.unlock();
freeSpace.release();
}
std::cerr << std::endl;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Producer producer;
Producer1 producer1;
Producer2 producer2;
Consumer consumer;
producer.start();//通过调用run来执行线程
producer1.start();
producer2.start();
consumer.start();
producer.wait();//wait()和pthread_join()功能类似
producer1.wait();//wait()和pthread_join()功能类似
producer2.wait();//wait()和pthread_join()功能类似
consumer.wait();
return a.exec();
}