Qt文档阅读笔记-Semaphores Example解析(信号量并发实例)

这个例子展示了在Qt中使用多线程,在并发程序中使用QSemaphore要比QMutex高级。

这个例子是生产者生成数据,消费者消费数据,QSemaphore等同于QWaitCondition + QMutex。

 

下面的这些代码中

const int DataSize = 100000;

const int BufferSize = 8192;
char buffer[BufferSize];

QSemaphore freeBytes(BufferSize);
QSemaphore usedBytes;

 

这里的DataSize是循环的总次数,freeBytes(BufferSize)是指目前freeBytes的阈值为8192,而usedBytes的阈值为0,这个阈值的作用将会在下面说明。

 

下面来看下生产者代码:

class Producer : public QThread
 {
 public:
     void run() override
     {
         for (int i = 0; i < DataSize; ++i) {
             freeBytes.acquire();
             buffer[i % BufferSize] = "ACGT"[QRandomGenerator::global()->bounded(4)];
             usedBytes.release();
         }
     }
 };

 

从中可以看到生产者开了一个线程去操作,freeBytes.acquire()他的作用是需要获取一个数据,当调用了这个函数后其available()的返回值,也就是资源数量就会减少1,如果调用为freeBytes.acquire(5)那么将会减少5,但是如果不够减少,那么就不会减少,这个线程就和被挂起,等待freeBytes有数据后就会被激活。而这个usedBytes.release()会生成一个资源,也就是说usedBytes.available()其返回值会比以前加1,这里也可以填写参数usedBytes.release(5).

 

下面是消费者代码:

class Consumer : public QThread
 {
     Q_OBJECT
 public:
     void run() override
     {
         for (int i = 0; i < DataSize; ++i) {
             usedBytes.acquire();
             fprintf(stderr, "%c", buffer[i % BufferSize]);
             freeBytes.release();
         }
         fprintf(stderr, "\n");
     }
 };

 

同样消费者也是一个线程,usedBytes的默认的阈值为0,usedBytes.acuire()如果为0就将其阻塞掉。同样freeBytes将会+1,这里是不会被阻塞的,能阻塞的地方只有usedBytes.acquire()。这里的阻塞用怎么的词汇应该是挂起。

 

下面是main函数:

int main(int argc, char *argv[])
 {
     QCoreApplication app(argc, argv);
     Producer producer;
     Consumer consumer;
     producer.start();
     consumer.start();
     producer.wait();
     consumer.wait();
     return 0;
 }

在main函数中有一个要注意的就是wait,使用这个可以进行等待,等生产者和消费线程完成后才会return 0;

最后生产者生产一个数据就会被使用,消费者被usedBytes信号量阻塞挂起了,生产者产生一个就和被消费。这里再给出一个程序截图:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章