您好,登錄后才能下訂單哦!
生產者——消費者模型中,生產者和消費者線程之間需要傳遞一定量的數據,兩個線程會使用一個特定大小的共享環形緩沖器。
生產者向緩沖器中寫入數據,直到它到達緩沖器的終點;然后它會再次從起點重新開始,覆蓋已經存在的數據。消費者線程則會讀取生成的數據。
在生產者——消費者實例中,對于同步的需求有兩個部分:如果生產者線程生成數據的速度太快,那么將會把消費者線程還沒有讀取的數據覆蓋;如果消費者線程讀取數據的速度過快,那么它就會越過生產者線程而讀取一些垃圾數據。
解決這一問題的一個粗略方法是,讓生產者線程填滿緩沖器,然后等待消費者線程讀取完緩沖器中全部速度。
另一個更有效的方案是使用兩個信號量。
freeSpace信號量控制生產者線程寫入數據的那部分緩沖器,usedSpace信號量則控制消費者線程讀取數據的那部分緩沖器區域。這兩個區域是相互補充的。常用緩沖區容量值初始化freeSpace信號量,意味著它最多可以獲取的緩沖器資源量。在啟動這個應用程序時,消費者線程就會獲得自由的字節并把它們轉換為用過的字節。用0初始化usedSpace信號量,以確保消費者線程不會在一開始就讀取到垃圾數據。
在生產者線程中,每次反復寫入都是從獲取一個自由字節開始。如果該緩沖器中充滿了消費者線程還沒有讀取的數據,那么對acquire()的調用就會被阻塞,直到消費者線程開始消費這些數據。一旦生產者線程獲取這一字節,就寫入數據,并將這個字節釋放為用過的字節,以讓消費者線程讀取到。
在消費者線程中,我們從獲取一個用過的字節開始。如果緩沖器中還沒有任何可用的數據,那么將會阻塞對acquire()調用,直到生產者線程生產數據。一旦獲取到這個字節,就使用數據,并把字節釋放為自由的字節,這樣,生產者線程就可以再次寫入。
生產者把自由的空間轉換為用過的空間,消費者將用過的空間轉換為自由的空間。
[cpp] view plain copy
/**************************************
*說明:生產者——消費者線程模型
***************************************/
#include <QtCore/QCoreApplication>
#include <QSemaphore>
#include <QThread>
#include <stdio.h>
//
QSemaphore usedSem(0);//已用量
QSemaphore unusedSem(4096);//未使用變量
unsigned int buffer[4096];//緩沖區
//生產者線程
class producer:public QThread
{
public:
producer();
private:
void run();
};
producer::producer()
{
;
}
//
void producer::run()
{
int i=0;
for(i=0;i<10000;i++)
{
unusedSem.acquire();//空閑信號量減1
buffer[i%4096]=i;
usedSem.release();//已用信號量加1
}
}
//消費者線程
class customer:public QThread
{
public:
customer();
private:
void run();
};
customer::customer()
{
;
}
void customer::run()
{
int i=0;
for(i=0;i<10000;i++)
{
usedSem.acquire();//已用信號量減1
printf("%d\n",buffer[i%4096]);
unusedSem.release();//空閑信號量加1
}
}
//
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//
producer producerThread;
customer customerThread;
//
producerThread.start();
customerThread.start();
//
producerThread.wait();
customerThread.wait();
//
return a.exec();
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。