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信號量阻塞掛起了,生產者產生一個就和被消費。這裏再給出一個程序截圖:

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