/*
生产者和消费者实验使用信号量实现线程的同步
*/
#include <QtCore>
#include <iostream>
const int DataSize = 100;
const int BufferSize = 10;
char buffer[BufferSize];
//定义两个信号量
QSemaphore freeSpace(BufferSize);
QSemaphore usedSpace(0);//刚开始没有生产者写好的数据,所以初始化为0
//生产者
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];
std::cerr << "P";
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];
std::cerr <<"c";
freeSpace.release();
}
std::cerr << std::endl;
}
//主程序
int main()
{
Producer producer;
Consumer consumer;
producer.start();//通过调用run来执行线程
consumer.start();
producer.wait();//wait()和pthread_join()功能类似
consumer.wait();
return 0;
}
执行结果:
BufferSize 不同对应的结果也稍有不同
(1)
const int DataSize = 100;
const int BufferSize = 1;
PcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPc
(2)
const int DataSize = 100;
const int BufferSize = 10;
PPPPPPPPPPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcPcccccccccc
(3)
const int DataSize = 100;
const int BufferSize = 100;
PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc