1. 程式人生 > >【Qt多執行緒之訊號量】Qsemaphore

【Qt多執行緒之訊號量】Qsemaphore

訊號量

怎麼簡單的給自己解釋這個機制呢?

那就借這個小程式碼解釋吧

QSemaphore freeBytes(80);
QSemaphore usedBytes(0);

freeBytes.acquire();
buffer[i%BufferSize] = (i%BufferSize);
usedBytes.release();      

freeBytes(80)表示訊號量中的可用資源是80,而每次freeBytes.acquire()都會讓可用資源-1,直到可用資源=0時,這時候就會引發阻塞;

另一方面可以通過usedBytes.release()來釋放資源,每次release()都會讓可用資源+1,這時候又有可用資源了,阻塞的地方也就再次開始運行了。

例項

經典的訊號量說明機制:生產者和消費者

semaphore.h

#ifndef SEMAPHORE_H
#define SEMAPHORE_H

#include <QSemaphore>
#include <QThread>

class Producer : public QThread
{
public:
    Producer();
    void run();
};

class Consumer : public QThread
{
public:
    Consumer();
    void run();
};

#endif

semaphore.cpp

#include "semaphore.h"
#include <QtDebug>

const int DataSize = 1000;
const int BufferSize = 80;
int buffer[BufferSize];
QSemaphore freeBytes(BufferSize);
QSemaphore usedBytes(0);

/********消費者**********************************************/
Consumer::Consumer()
{

}

void Consumer::run()
{
    usedBytes.acquire();
    for
(int i = 0; i < DataSize; i++) { usedBytes.acquire(); qDebug() << buffer[i%BufferSize]; if (i % 16 == 0 && i != 0) qDebug() << "\n"; freeBytes.release(); } } /********生產者**********************************************/ Producer::Producer() { } void Producer::run() { for (int i = 0; i < DataSize; i++) { freeBytes.acquire(); buffer[i%BufferSize] = (i%BufferSize); usedBytes.release(); //每次讀入一個數,告知消費者可以讀數了 } }

main.cpp

//Application這個類是繼承QCoreApplication的,而QCoreApplication有繼承

//QObject的,而QObject就是QT中最基本的基類,也就是QT的根基了,

//.acquire() 每使用一次,引用計數-1
//.release() 每使用一次,引用計數+1

#include <QCoreApplication>
#include "semaphore.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Producer p;
    Consumer c;

    p.start();
    c.start();

    p.wait();
    c.wait();
    return a.exec();
}