第一篇:實驗4生產者消費者問題報告
南京信息工程大學 實驗(實習)報告
實驗(實習)名稱 生產者-消費者問題的模擬實現(xiàn) 實驗(實習)日期 2014.11.30 得分 指導教師 陳遙
系 計算機
專業(yè) 計科 年級 12級
班次 2 姓名 唐薇 學號 20122308061
一、實驗目的
本實驗的目的是通過編寫和調試一個解決生產者–消費者問題的簡單模擬程序,進一步深入理解課堂教學中講授的進程同步問題,以及用于解決同步問題的信號量機制的基本思想,即通過研究進程同步和信號量機制實現(xiàn)生產者消費者問題的并發(fā)控制,以便階段性地鞏固學習成果。
二、實驗內容
(1)概述
說明:有界緩沖區(qū)內設有20個存儲單元,放入/取出的數(shù)據項設定為1-20這20個整型數(shù)。
編制程序模擬解決生產者-消費者同步問題。具體設計要求:(1)每個生產者和消費者對有界緩沖區(qū)進行操作后,即時顯示有界緩沖區(qū)的全部內容,當前指針位置和生產者/消費線程的標識符。(2)生產者和消費者各有兩個以上。(3)多個生產者或多個消費者之間須有共享對緩沖區(qū)進行操作的函數(shù)代碼。(2)設計原理
通過一個有界緩沖區(qū)把生產者和消費者聯(lián)系起來。假定生產者和消費者的優(yōu)先級是相同的,只要緩沖區(qū)未滿,生產者就可以生產產品并將產品送入緩沖區(qū)。類似地,只要緩沖區(qū)未空,消費者就可以從緩沖區(qū)中取走產品。應該禁止生產者向滿的緩沖區(qū)送入產品,同時也應該禁止消費者從空的緩沖區(qū)中取出產品,這一機制由生產者線程和消費者線程之間的互斥關系來實現(xiàn)。與計算打印兩進程同步關系相同,生產者和消費者兩進程Producer和Consumer之間應滿足下列兩個同步條件:
? 只有在緩沖池中至少有一個緩沖區(qū)已存入消息后,消費者才能從中提取信息,否則消費者必須等待。
? 只有緩沖池中至少有一個緩沖區(qū)是空時,生產者才能把消息放入緩沖區(qū),否則生產者必須等待。
為了滿足第一個同步條件,設置一個同步信號量full,它代表的資源是緩沖區(qū)滿,它的初始值為0,它的值為n時整個緩沖池滿。這個資源是消費者進程Consumer所有,Consumer進程可以申請該資源,對它施加P操作,而Consumer進程的合作進程生產者進程Producer對它施加V操作。同樣為了滿足第二個同步條件,設置另一個同步信號量empty,它代表的資源是緩沖空區(qū),它的初始值為n,表示緩沖池中所有緩沖區(qū)空。信號量full表示可用緩沖區(qū)數(shù)量,信號量empty表示緩沖區(qū)數(shù)量,設置整型變量:存入指針in和取出指針out。
為解決生產者/消費者問題,應該設置兩個資源信號量,其中一個表示空緩沖區(qū)的數(shù)目,用g_hFullSemaphore表示,其初始值為有界緩沖區(qū)的大小SIZE_OF_BUFFER;另一個表示緩沖區(qū)中產品的數(shù)目,用g_hEmptySemaphore表示,其初始值為0。另外,由于有界緩沖區(qū)是一個臨界資源,必須互斥使用,所以還需要在設置一個互斥信號量g_hMutex,初始值為1.P原語的主要動作是:
? sem(信號量)減1;
? 若sem減一后仍大于或等于零,則進程繼續(xù)執(zhí)行;
? 若sem減一后小于零,則該進程被阻塞后入與該信號相對應的隊列中,然后轉進程調度。V原語的操作主要動作是:
? sem加1;
? 若相加結果大于零,進程繼續(xù)執(zhí)行;
③若相加結果小于或等于零,則從該信號的等待隊列中喚醒一等待進程然后再返回原進程繼續(xù)執(zhí)行或轉進程調度。
采用的同步方法:
1)利用函數(shù)CreateMutex(NULL,FALSE,NULL)創(chuàng)建互斥信號量g_hMutex,表示緩沖區(qū)當前的狀態(tài),若為true時,則表示緩沖區(qū)正被別的進程使用。三個參數(shù)表示的意義分別為:指向安全屬性的指針,初始化互斥對象的所有者,指向互斥對象名的指針。
2)利用函數(shù)CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1, NULL)創(chuàng)建緩沖區(qū)空的信號量g_hFullSemaphore,值為true時表示緩沖區(qū)已滿。四個參數(shù)分別為:表示是否允許繼承、設置信號機的初始計數(shù)、設置信號機的最大計數(shù)、指定信號機對象的名稱(-1是因為計數(shù)從開始)。
3)利用函數(shù)CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL)創(chuàng)建緩沖區(qū)滿的信號量g_hEmptySemaphore,該值為true時表示緩沖區(qū)為空。
程序清單 1.存儲結構定義
利用信號量解決生產者消費者問題
const unsigned short SIZE_OF_BUFFER = 20;//緩沖區(qū)長度 unsigned short ProductID = 0;//產品號
unsigned short ConsumeID = 0;//將被消耗的產品號
unsigned short in = 0;//產品進緩沖區(qū)時的緩沖區(qū)下標 unsigned short out = 0;//產品出緩沖區(qū)時的緩沖區(qū)下標 int g_buffer[SIZE_OF_BUFFER];//緩沖區(qū)是個循環(huán)隊列 bool g_continue = true;//控制程序結束 HANDLE g_hMutex;//用于線程間的互斥
HANDLE g_hFullSemaphore;//當緩沖區(qū)滿時迫使生產者等待 HANDLE g_hEmptySemaphore;//當緩沖區(qū)空時迫使消費者等待 DWORD WINAPI Producer(LPVOID);//生產者線程 DWORD WINAPI Consumer(LPVOID);//消費者線程
2.算法相關的函數(shù)
(1)創(chuàng)建各個互斥信號以及生產者線程和消費者線程的函數(shù)在如下主函數(shù)里面所示: int main(){ //創(chuàng)建各個互斥信號
g_hMutex = CreateMutex(NULL,FALSE,NULL);g_hFullSemaphore=CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL);g_hEmptySemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL);//調整下面的數(shù)值,可以發(fā)現(xiàn),當生產者個數(shù)多于消費者個數(shù)時,//生產速度快,生產者經常等待消費者;反之,消費者經常等待。const unsigned short PRODUCERS_COUNT = 3;//生產者的個數(shù) const unsigned short CONSUMERS_COUNT = 1;//消費者的個數(shù) //總的線程數(shù)
const unsigned short THREADS_COUNT=PRODUCERS_COUNT+CONSUMERS_COUNT;HANDLE hThreads[THREADS_COUNT];//各線程的handle DWORD producerID[PRODUCERS_COUNT];//生產者線程的標識符 DWORD consumerID[CONSUMERS_COUNT];//消費者線程的標識符 //創(chuàng)建生產者線程
for(int i=0;i< PRODUCERS_COUNT;++i){ hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);if(hThreads[i]==NULL)return-1;} //創(chuàng)建消費者線程
for(i=0;i //生產一個產品。簡單模擬了一下,僅輸出新產品的ID號 void Produce(){ std::cerr << “Producing ” << ++ProductID << “ *** ”;std::cerr << “Succeed” << std::endl;}(3)把新生產的產品放入緩沖區(qū)的函數(shù): //把新生產的產品放入緩沖區(qū) void Append(){ std::cerr << “Appending a product *** ”;g_buffer[in] = ProductID;in =(in+1)%SIZE_OF_BUFFER;std::cerr << “Succeed” << std::endl;}(4)輸出緩沖區(qū)當前的狀態(tài)的代碼: //輸出緩沖區(qū)當前的狀態(tài) for(int i=0;i for(int i=0;i DWORD WINAPI Producer(LPVOID lpPara){ while(g_continue){ WaitForSingleObject(g_hFullSemaphore,INFINITE);WaitForSingleObject(g_hMutex,INFINITE);Produce();Append();Sleep(1500);ReleaseMutex(g_hMutex);ReleaseSemaphore(g_hEmptySemaphore,1,NULL);} return 0;}(2)消費者算法: //消費者 DWORD WINAPI Consumer(LPVOID lpPara){ while(g_continue){ WaitForSingleObject(g_hEmptySemaphore,INFINITE);WaitForSingleObject(g_hMutex,INFINITE);Take();Consume();Sleep(1500);ReleaseMutex(g_hMutex);ReleaseSemaphore(g_hFullSemaphore,1,NULL);} return 0;} ? 運行結果分析 輸入輸出數(shù)據說明和分析: 該程序設置的緩沖區(qū)數(shù)據長度為20,生產者個數(shù)為3,消費者個數(shù)為1,程序啟動后,生產者先進行生產,當3個生產者全部生產完之后,消費者開始從緩沖區(qū)中取出產品,當消費者取出一個后,生產者開始繼續(xù)生產,當生產完3個之后,消費者開始從緩沖池中取產品,依次循環(huán)。 三、小結 通過本次試驗,我對操作系統(tǒng)中線程,進程同步互斥等知識的應用有了更深的了解,我知道了生產者—消費者問題是很著名的同步問題,的確是既簡單又復雜。 實 驗 二 經 典 的 生 產 者 — 消 費 者 問 題 一、目的 實現(xiàn)對經典的生產者—消費者問題的模擬,以便更好的理解經典進程同步問題。 二、實驗內容及要求 編制生產者—消費者算法,模擬一個生產者、一個消費者,共享一個緩沖池的情形。 1、實現(xiàn)對經典的生產者—消費者問題的模擬,以便更好的理解此經典進程同步問題。生產者- 消費者問題是典型的 PV 操作問題,假設系統(tǒng)中有一個比較大的緩沖池,生產者的任務是只要緩沖池未滿就可以將生產出的產品放入其中,而消費者的任務是只要緩沖池未空就可以從緩沖池中拿走產 品。緩沖池被占用時,任何進程都不能訪問。 2、每一個生產者都要把自己生產的產品放入緩沖池,每個消費者從緩沖池中取走產品消費。在這種情況下,生產者消費者進程同步,因為只有通過互通消息才知道是否能存入產品或者取走產品。他們之間也存在互斥,即生產者消費者必須互斥訪問緩沖池,即不能有兩個以上的進程同時進行。 三、生產者和消費者原理分析 在同一個進程地址空間內執(zhí)行兩個線程。 生產者線程生產物品,然后將物品放置在一個空緩沖區(qū)中供消費者線程消費。 消費者線程從緩沖區(qū)中獲得物品,然后釋放緩沖區(qū)。 當生產者線程生產物品時,如果沒有空緩沖區(qū)可用,那么生產者線程必須等待消費者線程釋放一個空緩沖區(qū)。 當消費者線程消費物品時,如果沒有滿的緩沖區(qū),那么消費者線程將被阻擋,直到新的物品被生產出來。 四、生產者與消費者功能描述: 生產者功能描述:在同一個進程地址空間內執(zhí)行兩個線程。生產者線程生產物品,然后將物品放置在一個空緩沖區(qū)中供消費者線程消費。當生產者線程生產物品時,如果沒有空緩沖區(qū)可用,那么生產者線程必須等待消費者線程釋放出一個空緩沖區(qū)。 消費者功能描述:消費者線程從緩沖區(qū)獲得物品,然后釋放緩沖區(qū),當消費者線程消費物品時,如果沒有滿的緩沖區(qū),那么消費者線程將被阻塞,直到新的物品被生產出來。 五、實驗環(huán)境 操作系統(tǒng)環(huán)境: Windows 系統(tǒng)。編程語言: C#。 六、生產者與消費者的思路和設計 1、程序流程圖 (1)生產者 開 始 生產產品 Wait empty ≤ 0 Y N Wait 緩沖區(qū)內已滿,已無 可用緩沖區(qū) N Mutex=1 Y 緩沖區(qū)正被其他 程占用 進 存入緩沖區(qū) empty = empty-1 Signal Signal(full)結 束 (2)消費者 開 始 Wait(full)消費請求 full ≤ 0 Y N Wait 緩沖區(qū)內產品已空,不能進行消費 N Mutex=1 Y 消 費 緩沖區(qū)正被其他 程占用 進 full = full-1 Signal Signal 結 束 2、主要程序代碼 // 初始化變量 private void Form1_Load(object sender, EventArgs e){ mutex = 1;// 互斥信號量 full = 0;// 緩沖池中滿緩沖區(qū)的數(shù)量 empty = 5;// 緩沖池中空緩沖區(qū)的數(shù)量 count1 = 0;// 生產的產品數(shù)目 i = 0;= “1”;= “0”;= “5”;} // 消費者從緩沖區(qū)中消費一個產品 private void consumer_Click(object sender, EventArgs e){ if(full > 0){ // 消費者已進入互斥臨界區(qū) if(mutex == 1)// 申請進入臨界區(qū) { mutex = 0;// 消費者已進入互斥臨界區(qū) = “0”;= true;// 啟動消費者消費緩沖區(qū)產品 } else {(“ 緩沖區(qū)被占用,請等待。。 ”, “ 信息提 ”;} } else {(“ 緩沖區(qū)為空,不能消費!”, “ 信息提示 ”,;} } // 生產者向緩沖區(qū)中存入一個產品 private void producer_Click(object sender, EventArgs e){ count1 = count1 + if(empty > 0){ 1; // // 生產一個產品 有緩沖區(qū)可放產品 if(mutex == 1){ // 申請進入臨界區(qū) mutex = 0; // 生產者已進入臨界區(qū) = “0”; ();// 啟動生產者將產品放入緩沖區(qū) } else { // 不能進入臨界區(qū) count1 = count1-1;(“ 緩沖區(qū)被占用,請等待。。 ”, “ 信息提示 ”,;} } else {(“ 緩沖區(qū)已滿!”, “ 信息提示 ”,;// 無緩沖區(qū)可放產品 count1 = count1-1;} } // 生產者 private void timer1_Tick_1(object sender, EventArgs e){ if(bool1){ switch(count1){ case 1: = true;break;case 2: = true;break;case 3: = true;break;case 4: = true;break;case 5: = true;break;} = “ 生產者進程占用緩沖區(qū),請等待。。 ”;bool1 = false;} else { switch(count1){ case 1: = false;break;case 2: = false;break;case 3: = false;break;case 4: = false;break;case 5: = false;break;} = “ 生產者進程占用緩沖區(qū),請等待。。 ”;bool1 = true;} i = i + 1;if(i == 5) { // 循環(huán)緩沖區(qū),首尾相接 i = 0;= false;mutex = 1;= “1”;switch(count1){ case 1: = true;break;case 2: = true;break;case 3: = true;break;case 4: = true;break;case 5: = true;break;} full = full + 1;=();empty = empty-1;=();= “ 生產結束!”;} } // 消費者 private void timer_consumer_Tick(object sender, EventArgs e){ if(bool1){ switch(count1){ case 1: = true;break;case 2: = true;break;case 3: = true;break;case 4: = true;break;case 5: = true;break;} = “ 消費者進程占用緩沖區(qū),請等待。。 ”;bool1 =false;} else{ switch(count1){ case 1: = false;break;case 2: = false;break;case 3: = false;break;case 4: = false;break;case 5: = false;break;} = “ 消費者進程占用緩沖區(qū),請等待。。 ”;bool1= true;} i = i + 1;if(i==5){ i = 0;= false;mutex = 1;= “1”;switch(count1){ case 1: = false;break;case 2: = false;break;case 3: = false;break;case 4: = false;break;case 5: = false;break;} count1 = count1-1;full = full-1;=();empty = empty+1;=();=“ 消費結束! ”;} 3、運行界面和運行結果 一般情況下,點一次生產者按紐,mutex 由 1 變?yōu)?0,緩沖區(qū)呈現(xiàn)閃爍狀態(tài)(表示正在存儲),此時不可以再進行緩沖區(qū)操作,否則將顯示“生產者進程正在占用緩沖區(qū),請等待”。閃爍約秒后,mutex 由 0 變?yōu)?1,閃爍停止,表示存儲過程結束;點一次消費者按紐,mutex 由 1 變?yōu)?0,緩沖區(qū)呈現(xiàn)閃爍狀態(tài)(表示正在消費),此時不可以再進行緩沖區(qū)操作,否則將顯示“消費者進程正在占用緩 沖區(qū),請等待”。閃爍約秒后,mutex 由 0 變?yōu)?1,閃爍停止,表示消費過程結束。緩沖池滿后,若再點生產者按紐,會給出信息提示: “緩沖區(qū)已滿!”。 緩沖池空后,若再點消費者按紐,也會給出信息提示: “緩沖區(qū)為空,不能消費!”。 在存儲狀態(tài)或消費狀態(tài)(閃爍狀態(tài)),無論是點生產者按紐還是消費者按紐都會給出“緩沖區(qū)被占用,請等待。”信息提示。 七、心得體會 本次實驗是關于生產者與消費者之間互斥和同步的問題。問題的是指是 P、V 操作,實驗設一個共享緩沖區(qū),生產者和消費者互斥的使用,當一個線程使用緩沖區(qū)的時候,另一個讓其等待直到前一 個線程釋放緩沖區(qū)為止。 生產者與消費者是一個與現(xiàn)實有關的經驗問題,通過此原理舉一反三可以解決其他類似的問題。 通過本實驗設計,我們對操作系統(tǒng)的 P、V 進一步的認識,深入的了解 P、V 操作的實質和其重 要性。課本的理論知識進一步闡述了現(xiàn)實中的實際問題。 實驗中,我們小組分工合作,共同學習,雖然在實驗中遇到了一些問題,但在老師和同學的細心指導和熱心幫助下解決了。同時,了解到團隊精神的重要性,也為以后的學習和工作打下了堅實的基礎,同時積累了寶貴的經驗。 實驗報告五 ——生產者和消費者問題 姓名:叢菲 學號:20100830205 班級:信息安全二班 一、實習內容 ? ? 1、模擬操作系統(tǒng)中進程同步和互斥 2、實現(xiàn)生產者和消費者問題的算法實現(xiàn) 二、實習目的 ? ? ? ? ? 1、熟悉臨界資源、信號量及PV操作的定義與物理意義 2、了解進程通信的方法 3、掌握進程互斥與進程同步的相關知識 4、掌握用信號量機制解決進程之間的同步與互斥問題 5、實現(xiàn)生產者-消費者問題,深刻理解進程同步問題 三、實習題目 ? 在Linux操作系統(tǒng)下用C實現(xiàn)經典同步問題:生產者—消費者,具體要求如下: (1)一個大小為10的緩沖區(qū),初始狀態(tài)為空。 (2)2個生產者,隨機等待一段時間,往緩沖區(qū)中添加數(shù)據,若緩沖區(qū)已滿,等待消費者取走數(shù)據之后再添加,重復10次。 (3)2個消費者,隨機等待一段時間,從緩沖區(qū)中讀取數(shù)據,若緩沖區(qū)為空,等待生產者添加數(shù)據之后再讀取,重復10次。? 提示 本實驗的主要目的是模擬操作系統(tǒng)中進程同步和互斥。在系統(tǒng)進程并發(fā)執(zhí)行異步推進的過程中,由于資源共享和進程間合作而造成進程間相互制約。進程間的相互制約有兩種不同的方式。 (1)間接制約。這是由于多個進程共享同一資源(如CPU、共享輸入/輸出設備)而引起的,即共享資源的多個進程因系統(tǒng)協(xié)調使用資源而相互制約。 (2)直接制約。只是由于進程合作中各個進程為完成同一任務而造成的,即并發(fā)進程各自的執(zhí)行結果互為對方的執(zhí)行條件,從而限制各個進程的執(zhí)行速度。 生產者和消費者是經典的進程同步問題,在這個問題中,生產者不斷的向緩沖區(qū)中寫入數(shù)據,而消費者則從緩沖區(qū)中讀取數(shù)據。生產者進程和消費者對緩沖區(qū)的操作是互斥,即當前只能有一個進程對這個緩沖區(qū)進行操作,生產者進入操作緩沖區(qū)之前,先要看緩沖區(qū)是否已滿,如果緩沖區(qū)已滿,則它必須等待消費者進程將數(shù)據取出才能寫入數(shù)據,同樣的,消費者進程從緩沖區(qū)讀取數(shù)據之前,也要判斷緩沖區(qū)是否為空,如果為空,則必須等待生產者進程寫入數(shù)據才能讀取數(shù)據。 在本實驗中,進程之間要進行通信來操作同一緩沖區(qū)。一般來說,進程間的通信根據通信內容可以劃分為兩種:即控制信息的傳送與大批量數(shù)據傳送。有時,也把進程間控制在本實驗中,進程之間要進行通信來操作同一緩沖區(qū)。一般來說,進程間的通信根據通信內容可以劃分為兩種:即控制信息的傳送與大批量數(shù)據傳送。有時,也把進程間控制信息的交換稱為低級通信,而把進程間大批量數(shù)據的交換稱為高級通信。 目前,計算機系統(tǒng)中用得比較普遍的高級通信機制可分為3大類:共享存儲器系統(tǒng)、消息傳遞系統(tǒng)及管道通信系統(tǒng)。 ? 共享存儲器系統(tǒng) 共享存儲器系統(tǒng)為了傳送大量數(shù)據,在存儲器中劃出一塊共享存儲區(qū),諸進程可通過對共享存儲區(qū)進行讀數(shù)據或寫數(shù)據以實現(xiàn)通信。進程在通信之前,向系統(tǒng)申請共享存儲區(qū)中的一個分區(qū),并為它指定一個分區(qū)關鍵字。信息的交換稱為低級通信,而把進程間大批量數(shù)據的交換稱為高級通信。 目前,計算機系統(tǒng)中用得比較普遍的高級通信機制可分為3大類:共享存儲器系統(tǒng)、消息傳遞系統(tǒng)及管道通信系統(tǒng)。 ? 消息傳遞系統(tǒng) 在消息傳遞系統(tǒng)中,進程間的數(shù)據交換以消息為單位,在計算機網絡中被稱為報文。消息傳遞系統(tǒng)的實現(xiàn)方式又可以分為以下兩種:(1)直接通信方式 發(fā)送進程可將消息直接發(fā)送給接收進程,即將消息掛在接收進程的消息緩沖隊列上,而接收進程可從自己的消息緩沖隊列中取得消息。(2)間接通信方式 發(fā)送進程將消息發(fā)送到指定的信箱中,而接收進程從信箱中取得消息。這種通信方式又稱信箱通信方式,被廣泛地應用于計算機網絡中。相應地,該消息傳遞系統(tǒng)被稱為電子郵件系統(tǒng)。 ? 管道通信系統(tǒng) 向管道提供輸入的發(fā)送進程,以字符流方式將大量的數(shù)據送入管道,而接收進程從管道中接收數(shù)據。由于發(fā)送進程和接收進程是利用管道進行通信的,故稱為管道通信。為了協(xié)調發(fā)送和接收雙方的通信,管道通信機制必須提供以下3方面的協(xié)調功能。(1)互斥 當一個進程正在對pipe文件進行讀或寫操作時,另一個進程必須等待。(2)同步 當寫進程把一定數(shù)量的數(shù)據寫入pipe文件后,便阻塞等待,直到讀進程取走數(shù)據后,再把寫進程喚醒。 (3)確認對方是否存在 只有確定對方已存在時,才能進行管道通信,否則會造成因對方不存在而無限制地等待。在這個問題當中,我們采用信號量機制進行進程之間的通信,設置兩個信號量,空的信號量和滿的信號量。在Linux系統(tǒng)中,一個或多個信號量構成一個信號量集合。使用信號量機制可以實現(xiàn)進程之間的同步和互斥,允許并發(fā)進程一次對一組信號量進行相同或不同的操作。每個P、V操作不限于減1或加1,而是可以加減任何整數(shù)。在進程終止時,系統(tǒng)可根據需要自動消除所有被進程操作過的信號量的影響 1.緩沖區(qū)采用循環(huán)隊列表示,利用頭、尾指針來存放、讀取數(shù)據,以及判斷隊列是否為空。緩沖區(qū)中數(shù)組大小為10; 2.利用隨機函數(shù)rand()得到A~Z的一個隨機字符,作為生產者每次生產的數(shù)據,存放到緩沖區(qū)中; 3.使用shmget()系統(tǒng)調用實現(xiàn)共享主存段的創(chuàng)建,shmget()返回共享內存區(qū)的ID。對于已經申請到的共享段,進程需把它附加到自己的虛擬空間中才能對其進行讀寫。 4.信號量的建立采用semget()函數(shù),同時建立信號量的數(shù)量。在信號量建立后,調用semctl()對信號量進行初始化,例如本實習中,可以建立兩個信號量SEM_EMPTY、SEM_FULL,初始化時設置SEM_EMPTY為10,SEM_FULL為0。使用操 作信號的函數(shù)semop()做排除式操作,使用這個函數(shù)防止對共享內存的同時操作。對共享內存操作完畢后采用shmctl()函數(shù)撤銷共享內存段。 5.使用循環(huán),創(chuàng)建2個生產者以及2個消費者,采用函數(shù)fork()創(chuàng)建一個新的進程。6.一個進程的一次操作完成后,采用函數(shù)fflush()刷新緩沖區(qū)。7.程序最后使用semctl()函數(shù)釋放內存。模擬程序的程序流程圖如下所示: 1.主程序流程圖: 2.生產者進程流程圖 3.消費者進程流程圖 4.P操作流程圖 5.V操作流程圖 四、實現(xiàn)代碼為: // exet5.cpp //#include “stdafx.h” #include = {7,10,1,2,10,3,10,4,2,3,10,3,2,1,2,10,1,7,10,1};void build();void LRU(); int main(intargc, char *argv[]){ printf(“Random sequence is as follows:n”);build();printf(“nInvoking LRU Algorithn: n”);LRU();return 0;} void build(){ inti = 0;for(i=0;i { process[i] =(int)(10.0*rand()/(RAND_MAX));printf(“%d ”,process[i]); } printf(“n”);} void LRU(){ int flag[mSIZE] = {0};inti = 0, j = 0;int m =-1, n =-1;int max =-1,maxflag = 0;int count = 0;for(i = 0;i //Find the first free Physical Block for(j=0;j { if(memery[j] == 0) { m = j;break; } } //Find if there are same processes for(j = 0;j { if(memery[j] == process[i]) { n = j; } } //Find free PB for(j = 0;j { if(flag[j]>maxflag) { maxflag = flag[j];max = j; } } if(n ==-1)// Find no same process { if(m!=-1)// find free PB { memery[m] = process[i];flag[m] = 0;for(j = 0;j <= m;j++) { flag[j]++; } m =-1; } else //NO find free PB { memery[max] = process[i];flag[max] = 0; for(j = 0;j { flag[j]++; } max =-1;maxflag = 0;count++; } } else // Find same process { memery[n] = process[i];flag[n] = 0;if(m!=-1)//find free PB { flag[m] = 0; } for(j = 0;j { flag[j]++; } max =-1;maxflag = 0; n =-1; } for(j = 0;j { printf(“%d ”,memery[j]); } printf(“n”);} printf(“nThe is: %dn”,count);} times of page conversion 五、在虛擬機上的具體操作及結果 執(zhí)行exe5.c文件 選擇Applications?Acecessories?Terminal,執(zhí)行文件: 依次預處理?編譯?匯編?連接?執(zhí)行用文件,編譯通過之后-o執(zhí)行。報錯!!錯誤顯示為很多頭文件沒有預定義。連續(xù)查找之后得知原因是鏈接不上pthread庫 在執(zhí)行命令后面加上-pthread,即新命令格式為:gcc-oexe5exe5.c–lpthread,重新執(zhí)行后的結果顯示如下截圖: 其中1表示緩沖區(qū)被生產者producer1或者二producer2寫入了Item,0表示沒有寫入數(shù)據或者被消費者consumer1或者consumer2消耗掉 六、實驗總結及思考 1、本次實驗是關于生產者與消費者之間互斥和同步的問題。問題的是指是P、V操作,實驗設一個共享緩沖區(qū),生產者和消費者互斥的使用,當一個線程使用緩沖區(qū)的時候,另一個讓其等待直到前一個線程釋放緩沖區(qū)為止。 2、實驗中包含的知識點很多,包括臨界區(qū)資源共享問題、信號量定義、PV操作流程、進程間的通信方式(消息傳遞和共享內存)、進程同步和互斥、信號量機制解決進程之間的同步與互斥問題等等。加深了對于本部分內容的理解 通過本實驗設計,我們對操作系統(tǒng)的P、V進一步的認識,深入的了解P、V操作的實質和其重要性。課本的理論知識進一步闡述了現(xiàn)實中的實際問題。 湖北民族學院信息工程學院11級計算機專業(yè)操作系統(tǒng)課程設計 (操作系統(tǒng)課程設計) 生 產 者 和 消 費 湖北民族學院信息工程學院11級計算機專業(yè)操作系統(tǒng)課程設計 者 學生姓名: 學生學號: 班 級: 0311401、02、03、04班制 二〇一三年十二月 一、課程題目分析 這個題目是生產者向消費者提供商品,消費者消耗商品,并且兩組人共用同一緩沖區(qū)。生產者提供了商品之后消費者才能去取商品,消費者若不取走商品則當緩沖區(qū)用完之后生產者則不能再向緩沖區(qū)中添加新的商品。 思考問題: (1)對于生產者進程:每產生一個數(shù)據,則需去訪問共用緩沖區(qū)是否有已滿,未滿則可以將該數(shù)據存入并通知消費者進程,否則不能。 (2)對于消費者進程:每當想去消費(取出數(shù)據)時,則需訪問緩沖區(qū)是否為空,為空則不能消費(取出數(shù)據),否則可以取,并通知生產者。 (3)緩沖區(qū)是個臨界資源,所有的進程對于該空間都是共享的,所以,還有互斥問題存在。 二、課程設計目的 通過實驗模擬生產者與消費者之間的關系,了解并掌握他們之間的關系及原理。由此增加對進程同步問題的了解: (1)掌握基本的同步互斥算法,理解生產者與消費者模型 (2)了解windows中多線程(多進程)的并發(fā)執(zhí)行機制,線程(進程)間的同步于互斥 (3)學習使用windows中基本的同步對象,掌握相應的API。 三、課程設計內容 有n個生產者和m個消費者,連接在具有k個單位緩沖區(qū)的有界環(huán)轉緩沖上,湖北民族學院信息工程學院11級計算機專業(yè)操作系統(tǒng)課程設計 故又稱有界緩沖問題。其中Pi和Cj都是并發(fā)進程,只要緩沖區(qū)未滿,生產者進程Pi所生產的產品就可投入緩沖區(qū);類似地,只要緩沖區(qū)非空,消費者進程Cj就可以從緩沖區(qū)取走并消耗產品。 四、開發(fā)環(huán)境 操作系統(tǒng):Windows系統(tǒng) 編寫語言:C++語言 五、系統(tǒng)分析設計 (一)算法原理 生產者——消費者問題是典型的進程同步問題,這些進程必須按照一定的生產率和消費率來訪問共享緩沖區(qū),用P、V操作解決生產者和消費者共享單緩沖區(qū)的問題,可設置兩個信號量empty和full,其初值分別為1和0,empty指示能否向緩沖區(qū)放入產品,full指示能否從緩沖區(qū)取出產品。為了使其協(xié)調工作,必須使用一個信號量mutex(初值為1),以限制生產者和消費者互斥地對緩沖區(qū)進行存取,另用兩個信號量empty1(初值為緩沖區(qū)大小)和full1(初值為0),以保證生產者不向已滿的緩沖區(qū)中放入產品,消費者不從空緩沖區(qū)中取產品。 (二)功能描述 生產者功能描述:在同一個進程地址空間內執(zhí)行兩個線程。生產者線程生產物品,然后將物品放置在一個空緩沖區(qū)中供消費者線程消費。當生產者線程生產物品時,如果沒有空緩沖區(qū)可用,那么生產者線程必須等待消費者線程釋放出一個空緩沖區(qū)。 消費者功能描述:消費者線程從緩沖區(qū)獲得物品,然后釋放緩沖區(qū),當消費者線程消費物品時,如果沒有滿的緩沖區(qū),那么消費者線程將被阻塞,直到新的物品被生產出來。 (三)算法流程圖 生產者流程圖: 消費者流程圖: 湖北民族學院信息工程學院11級計算機專業(yè)操作系統(tǒng)課程設計 總的流程圖: 湖北民族學院信息工程學院11級計算機專業(yè)操作系統(tǒng)課程設計 開始Int i=1,n鍵盤輸入數(shù)字,初始化 n SeqSquare *b;b=new SeqSquare(n);鍵盤輸入數(shù)字,改變i的值i==0?Y退出Ncout<<“請輸入正確的菜單項進行操作!”< (四)數(shù)據結構及部分函數(shù)描述 (1)類SeqSquare:對類SeqSquare的聲明及其中一些函數(shù) class SeqSquare { public: SeqSquare(int n);~SeqSquare();void P(int x);//p操作 void V(int x);//v操作 bool IsEmpty();//判斷是否為空 湖北民族學院信息工程學院11級計算機專業(yè)操作系統(tǒng)課程設計 bool IsFull();//判斷是否已滿 void deca();void decb();int getSize();int getmaxSize();int gettop();int geta();int getb();protected: private: };說明:①用動態(tài)整型數(shù)組*elements來代表緩沖區(qū),不管是生產產品還是對已有產品的消費都需要訪問該緩沖區(qū)。②函數(shù)IsFull()用于判斷緩沖區(qū)是否已滿,生產者能否使用緩沖區(qū)。③函數(shù)IsEmpty()用于判斷緩沖區(qū)是否為空,消費者能否使用緩沖區(qū)。 (2)生產者和消費者操作及顯示函數(shù)showbuf: void producer(SeqSquare *a)//生產者操作 { } void consumer(SeqSquare *a)//消費者操作 { } //緩沖區(qū)顯示 void showbuf(SeqSquare *a){ }(3)在實現(xiàn)本程序的生產者消費者模型時,具體地通過以下同步對象實現(xiàn)互斥: int *elements;int top,a,b,maxSize;a->P(1);a->V(1);int i=a->getSize();湖北民族學院信息工程學院11級計算機專業(yè)操作系統(tǒng)課程設計 ①設一個互斥量Mutex,以實現(xiàn)生產者在查詢和保留緩沖區(qū)的下一個空位置時進行互斥。 ②每一個生產者用一個信號量與消費者同步,通過設置Full實現(xiàn),該組信號量用于表示相應產品以生產。同時用一個表示空緩沖區(qū)數(shù)目的信號量Empty進行類似的同步,指示緩沖區(qū)中是否存在空位置,以便開始生產下一個產品。 (四)調試過程 為解決生產者、消費者問題,應該設置兩個資源信號量,其中一個表示空緩沖區(qū)的數(shù)目,用Full表示,其初值為用戶輸入的緩沖區(qū)的大小,另一個表示緩沖區(qū)中產品的數(shù)目,用Empty表示,其初值為0.另外,由于緩沖區(qū)是一個臨界資源,必須互斥使用,所以還需要再設置一個互斥信號量Mutex,其初值為1.在生產者、消費者問題中,信號量實現(xiàn)兩種功能。首先,他是生產產品和消費產品的計數(shù)器,計數(shù)器的初值是可使用的資源數(shù)目(緩沖區(qū)的長度)。其次,他是確保產品的生產者和消費者之間的動作同步的同步器。 生產者要生產一個產品時,首先對資源信號量Full和互斥信號量Mutex進行P操作,申請資源。如果可以通過的話,就生產一個產品,并把產品送人緩沖區(qū)。然后對互斥信號量Mutex和資源信號量Empty進行V操作,釋放資源。 消費者要消費一個產品時,首先對資源信號量Empty和互斥信號量Mutex進行P操作,申請資源。如果可以通過的話就從緩沖區(qū)取出一個產品并消費掉。然后對互斥信號量Mutex和資源信號量Full進行V操作,釋放資源。 如果緩沖區(qū)中已經沒有可用資源,就把申請資源的進程添加到等待隊列的隊尾。如果有一個資源被釋放,在等待隊列中的第一個進程被喚醒并取得這個資源的使用權。 (五)參考資料 《操作系統(tǒng)教程》 孫鐘秀 高等教育出版社 《C++程序設計》 譚浩強 高等教育出版社 六、運行實例及結果分析 (一)運行實例 緩沖區(qū)大小為3,先生產一件產品,顯示緩沖區(qū),再接著生產一件產品,消耗一件產品,顯示緩沖區(qū),在消耗兩件產品,再生產4件產品,改變緩沖區(qū)的大小為6,顯示緩沖區(qū),選擇一個未出現(xiàn)的選項,退出程序。 (二)結果顯示 湖北民族學院信息工程學院11級計算機專業(yè)操作系統(tǒng)課程設計 湖北民族學院信息工程學院11級計算機專業(yè)操作系統(tǒng)課程設計 (三)結果分析 (1)在每個程序中需要先做P,后做V,二者要成對出現(xiàn),夾在二者中間的代碼段就是該進程的臨界區(qū)。 (2)對同步信號量full和empty的P,V操作同樣必須成對出現(xiàn),但它們分別位于不同的程序中。 (3)無論在生產者進程中還是消費者進程中,兩個P操作的次序不能顛倒:應先執(zhí)行同步信號量的P操作,然后執(zhí)行互斥信號量的P操作。否則可能造成進程死鎖。 七、個人體驗 雖然我也很想用java語言寫這個程序,但是由于自己學藝不精,所以只能用C++寫。通過這個實驗我發(fā)現(xiàn)我以前有很多知識都忘記了,重新拿起課本學習9 湖北民族學院信息工程學院11級計算機專業(yè)操作系統(tǒng)課程設計 時發(fā)現(xiàn)原來很多不懂得問題都有了新的認識,有一種豁然開朗的感覺。也為我考研開了一個好的開頭。 我認為我完成的這個設計做的比較出色的地方是對C++語言中類以及數(shù)組的運用,其實這里我對數(shù)組的操作是按照“先進先出”的方法進行運作的,這是參考了棧的工作原理,因為緩沖區(qū)一般也是堆棧,比較符合設計要求。 這次實驗中我感覺做的很粗糙,自己所想的模擬過程的確得到實現(xiàn)了,但是感覺靈活性不太高,思考還不過全面,應該以后多注意一下,多考慮考慮才是。 在這次實驗中我重新將《C++程序設計》和《數(shù)據結構》的幾個重要章節(jié)復習了一遍,對類、數(shù)組、C++的I/O流類庫以及堆棧的語句格式、注意細節(jié)都再一次熟悉,感覺蠻有趣的。不過,在編程過程中許多語句的小問題還真是出現(xiàn)不少,而且感覺自己對C++強大豐富的語句方法用得太呆板,不夠靈活,總是想到那些常用的,而忽略了顆粒讓語句更簡短的方法,以后要多多注意才是。 八、附錄 // 生產者消費者1.cpp : Defines the entry point for the console application.// #include “stdafx.h” #include “iostream” using namespace std;class SeqSquare { public: SeqSquare(int n);~SeqSquare();void P(int x); //p操作 void V(int x); //v操作 bool IsEmpty(); //判斷是否為空 bool IsFull(); //判斷是否已滿 void deca();void decb();int getSize();int getmaxSize();int gettop();int geta();int getb();protected: private: int *elements;int top,a,b,maxSize;};10 湖北民族學院信息工程學院11級計算機專業(yè)操作系統(tǒng)課程設計 bool SeqSquare::IsEmpty() //判斷是否為空 { return(top==-1)?true:false;} bool SeqSquare::IsFull() //判斷是否已滿 { return(top>=maxSize-1)?true:false;} void SeqSquare::deca(){ a--;} void SeqSquare::decb(){ b--;} int SeqSquare::getSize(){ return top+1;} int SeqSquare::getmaxSize(){ return maxSize;} int SeqSquare::gettop(){ return top;} int SeqSquare::geta(){ return a;} int SeqSquare::getb(){ 湖北民族學院信息工程學院11級計算機專業(yè)操作系統(tǒng)課程設計 return b;} SeqSquare::SeqSquare(int n){ top =-1;a = b =0;maxSize = n;elements = new int[maxSize];} void SeqSquare::P(int x){ if(IsFull()==true){ a=a+1;} else { elements[++top] = x; } } void SeqSquare::V(int x){ if(IsEmpty()==true){ b = b+1;} else { x = elements[top--]; } } 湖北民族學院信息工程學院11級計算機專業(yè)操作系統(tǒng)課程設計 void producer(SeqSquare *a) //生產者操作 { a->P(1);} void consumer(SeqSquare *a) //消費者操作 { a->V(1);} SeqSquare::~SeqSquare(){ delete elements;} //緩沖區(qū)顯示 void showbuf(SeqSquare *a){ int i=a->getSize(); } int main(){ int i,n;cout<<“請輸入緩沖區(qū)大小:”< cout<<“請選擇操作: ”< 4.退出系統(tǒng)。 ”< ”< switch(i) { case 1: producer(s); if(s->geta()==0) { 湖北民族學院信息工程學院11級計算機專業(yè)操作系統(tǒng)課程設計 cout< } else { cout< s->deca(); } break; case 2: consumer(s); if(s->getb()==0) { cout< } else { cout< } break; case 3: showbuf(s); cout< ”<<“可用空間為:”<<(n-s->getSize())< break; case 4: cout< break; case 5: cout< cin>>n; s = new SeqSquare(n); cout< break; default: cout< } } return 0;} 閩江學院 計算機系 網絡操作系統(tǒng)課程設計 設計內容:進程機制與并發(fā)程序設計——linux下生產者與消費者的問題實現(xiàn) 目錄: 一、設計內容····························3 二、設計思想····························4 三、系統(tǒng)結構····························5 四、PV操作代碼··························5 五、C++程序代碼·························6 六、運行結果截圖························9 七、參考文獻····························11 八、實驗總結····························11 一、設計內容 進程機制與并發(fā)程序設計————linux下生產者與消費者的問題實現(xiàn) 1.實驗目的 (1)掌握基本的同步互斥算法,理解生產者和消費者同步的問題模型。(2)了解linux中多線程的并發(fā)執(zhí)行機制,線程間的同步和互斥。 2、實驗環(huán)境:C/C++語言編譯器 3、實驗要求 (1)創(chuàng)建生產者和消費者線程 在linux環(huán)境下,創(chuàng)建一個控制臺進程,在此進程中創(chuàng)建n個線程來模擬生產者或者消費者。這些線程的信息由本程序定義的“測試用例文件”中予以指定。 該文件的格式和含義如下: 3 1 P 3 2 P 4 3 C 4 1 4 P 2 5 C 3 1 2 4 第一行說明程序中設置幾個臨界區(qū),其余每行分別描述了一個生產者或者消費者線程的信息。每一行的各字段間用Tab鍵隔開。不管是消費者還是生產者,都有一個對應的線程號,即每一行開始字段那個整數(shù)。第二個字段用字母P或者C區(qū)分是生產者還是消費者。第三個字段表示在進入相應線程后,在進行生產和消費動作前的休眠時間,以秒計時;這樣做的目的是可以通過調整這一列參數(shù),控制開始進行生產和消費動作的時間。如果是代表生產者,則該行只有三個字段。如果代表消費者,則該行后邊還有若干字段,代表要求消費的產品所對應的生產者的線程號。所以務必確認這些對應的線程號存在并且該線程代表一個生產者。(2)生產和消費的規(guī)則 在按照上述要求創(chuàng)建線程進行相應的讀寫操作時,還需要符合以下要求: ①共享緩沖區(qū)存在空閑空間時,生產者即可使用共享緩沖區(qū)。 ②從上邊的測試數(shù)據文件例子可以看出,某一生產者生產一個產品后,可能不止一個消費者,或者一個消費者多次地請求消費該產品。此時,只有當所有的消費需求都被滿足以后,該產品所在的共享緩沖區(qū)才可以被釋放,并作為空閑空間允許新的生產者使用。 ③每個消費者線程的各個消費需求之間存在先后順序。例上述測試用例文件包含一行信息“5 C 3 l 2 4”,可知這代表一個消費者線程,該線程請求消費1,2,4號生產者線程生產的產品。而這種消費是有嚴格順序的,消費1號線程產品的請求得到滿足后才能繼續(xù)往下請求2號生產者線程的產品。 ④要求在每個線程發(fā)出讀寫操作申請、開始讀寫操作和結束讀寫操作時分別顯示提示信息。(3)相關基礎知識 本實驗所使用的生產者和消費者模型具有如下特點: 本實驗的多個緩沖區(qū)不是環(huán)形循環(huán)的,也不要求按順序訪問。生產者可以把產品放到目前某一個空緩沖區(qū)中。 消費者只消費指定生產者的產品。 在測試用例文件中指定了所有的生產和消費的需求,只有當共享緩沖區(qū)的數(shù)據滿足了所有關于它的消費需求后,此共享緩沖區(qū)才可以作為空閑空間允許新的生產者使用。 本實驗在為生產者分配緩沖區(qū)時各生產者間必須互斥,此后各個生產者的具體生產活動可以并發(fā)。而消費者之間只有在對同一產品進行消費時才需要互斥,同時它們在消費過程結束時需要判斷該消費對象是否已經消費完畢并清除該產品。 linux用來實現(xiàn)同步和互斥的實體。在linux中,常見的同步對象有:信號量(Semaphore)、互斥量(Mutex)、臨界段(CriticalSection)等。使用這些對象都分為三個步驟,一是創(chuàng)建或者初始化:接著請求該同步對象,隨即進入臨界區(qū),這一步對應于互斥量的上鎖;最后釋放該同步對象,這對應于互斥量的解鎖。這些同步對象在一個線程中創(chuàng)建,在其他線程中都可以使用,從而實現(xiàn)同步互斥。 二、設計思想 生產者進程與消費者進程是經典的同步互斥關系。系統(tǒng)創(chuàng)建兩類進程:proceducer()和consumer(),分別用來描述生產者和消費者的行為。生產者與消費者問題是指若干進程通過循環(huán)緩沖池區(qū)交換數(shù)據。如下圖所示,生產者進程不斷向循環(huán)緩沖池區(qū)中寫入數(shù)據(即生產數(shù)據),而消費者進程不斷從循環(huán)緩沖池區(qū)中讀出數(shù)據(即消費數(shù)據)。循環(huán)緩沖池共有N個緩沖區(qū),緩沖區(qū)可以暫存一個產品,任何時刻只能有一個進程課對循環(huán)緩沖池進行操作。所有生產者和消費者要協(xié)調工作,以完成數(shù)據的交換。只要有空緩沖區(qū),生產者就可以把產品送入緩沖區(qū);只要有滿緩沖區(qū),消費者就可以從緩沖區(qū)中取走物品。 為了解決生產者和消費者問題,應該設置信號量和變量如下: full: 滿緩沖區(qū)資源信號量,初值為0; empty:空緩沖區(qū)資源信號量,初值為n; in: 生產者指針,初值均為0; out: 消費者指針,均為0; mutex:緩沖區(qū)操作的互斥信號量,初值為1 三、系統(tǒng)結構 PCB* readyhead=NULL, * readytail=NULL;// 就緒隊列——鏈表結構 PCB* consumerhead=NULL, * consumertail=NULL;// 消費者隊列 PCB* producerhead=NULL, * producertail=NULL;// 生產者隊列 processproc()---給PCB分配內存,產生相應的的進程 Pempty()---如果緩沖區(qū)滿,該進程進入生產者等待隊列; linkqueue(exe,&producertail);// 把就緒隊列里的進程放入生產者隊列的尾部 執(zhí)行順序:Main()---empty---in---full---out---finish 當緩沖池為空時,生產者生產產品in緩沖池 in=in+1 當緩沖池為滿時,消費者消費產品out緩沖池 out=out+1 四、PV操作代碼 semaphore empty=n;semaphore full=0;semaphore mutex=1;message buffer[n];int in=0; int out=0;void main(){ parbegin(proceducer(),consumer());} void proceducer(){ do { prodece a new meddage;P(empty);P(mutex);send a new message to buffer[in];in=(in+1)%n;V(mutex);V(full);} while(true);} void consumer(){ do { P(full);P(mutex);get a message from buffer[out];out=(out+1)%n;V(mutex);V(empty);comsume a message;}while(true);} 五、C++程序代碼 #include “windows.h” #include “iostream.h” #include “math.h” #define random(rand()*10000)/RAND_MAX //定義一個隨機函數(shù)來生產產品,并且使兩個顧產品間的時間少于10秒 int long waiting(0);//正在等待的產品的數(shù)目 int buffer;//空位的總數(shù)目 char empty;//緩沖區(qū)空 char full;//緩沖區(qū)滿 int count(0);//產品的號碼數(shù) int finish(0);//生產完畢的產品數(shù)目 DWORD a;void proceduce() { Sleep(10000);cout<<“緩沖區(qū)已空!”< } void getconsum(){ Sleep(10001);//產品被生產的函數(shù),為了合理區(qū)分生產產品 cout<<“第”< HANDLE Mutex=CreateMutex(NULL, FALSE, “Mutex”);//用來實現(xiàn)進程的互斥 HANDLE proceducer=CreateSemaphore(NULL, 1,1, “proceducer”);//定義信號量來進行線程間的同步 HANDLE consumer=CreateSemaphore(NULL,0,3,“consum”);DWORD WINAPI consum(LPVOID pParm2)//消費的線程 { WaitForSingleObject(Mutex ,INFINITE);//p(mutex)來進行互斥操作 count++;//生產的是第幾個產品 cout<<“第 ”< { if(waiting!=0){ cout<<“此時有”< else cout<<“沒有產品在等待”< ReleaseMutex(Mutex);//釋放互斥量,以便其他線程使用 WaitForSingleObject(proceducer,INFINITE);//等待生產 getconsum();//消費并取走 } else { cout<<“緩沖區(qū)已滿,第”< return 0;} DWORD WINAPI proceducers(LPVOID pParm1)//生產者的線程 { while(true)//一直執(zhí)行 { WaitForSingleObject(consum,INFINITE);//p(customers),等待產品 WaitForSingleObject(Mutex,INFINITE);//等待互斥量 waiting--;//等待的產品數(shù)減一 ReleaseSemaphore(proceducer,1,NULL);//釋放信號量 ResumeThread(proceducer);//喚醒消費進程 ReleaseMutex(Mutex);//v(mutex);proceduce();//生產 finish++;//消費的產品數(shù)加1 } return 0;} int main(int argc, char* argv[]){ cout<<“請輸入緩沖區(qū)空位的總數(shù)目:”;cin>>buffer;cout<<“緩沖區(qū)共有”< cout< HANDLE hThread1;HANDLE hThread2;hThread2=::CreateThread(NULL,0,proceducers,NULL,0,NULL);//產生一個生產者進程 while(full!='y'){ Sleep(random);//產品隨機進入 hThread1=::CreateThread(NULL,0,consum,NULL,a,NULL);cout< { cout<<“已經為”< else;} if(full=='y'){ cout<<“********對不起,緩沖區(qū)已滿********”< } 六、運行結果截圖 緩沖區(qū)空位總數(shù)目為1時運行結果截圖: 緩沖區(qū)空位總數(shù)目為0和3時運行結果截圖(其余部分如上當緩沖區(qū)空位總數(shù)目為1時的截圖) 七、參考文獻 1、計算機網絡操作系統(tǒng)原理與應用 孔憲軍 呂濱(本學期教科書) 2、網絡操作系統(tǒng)課程設計計劃書 陳衛(wèi)老師 3、C程序設計(第三版)譚浩強 八、實驗總結 剛剛看到課程設計的內容與要求時,不禁有點無從下手的感覺。經過一番思考后,才決定選擇設計“進程機制與并發(fā)程序設計——linux下生產者與消費者的問題實現(xiàn)”這部分。設計這部分不僅僅需要用到C/C++編程,還需要編寫相關的PV原語。由于自己的PV原語部分和C/C++編程學的不是很好,因此對我來說有點難。于是我就積極利用書本上的知識來編寫PV原語,C/C++編程是參考書上的指點以及網絡資源編寫出來的。不懂得地方查資料、上網找、問問其他同學,最后終于慢慢的把課程設計做出來了。通過這次課程設計,才感覺到自己還是平時動手少,要經常動手去做實驗才能真正學到東西。尤其是一些C/C++編程和PV原語的編寫更需要平時多加練習才能學好用好。特別是C/C++編程在遇到語法有多處錯誤時,不能急,要冷靜下來慢慢修改,知道程序正確。雖然是自己獨立做的課程設計,但是其中還是有很多不懂的東西是問同學的,因此了解到學習不是單獨的,應該是相互交流相互學習的。第二篇:操作系統(tǒng)實驗報告經典生產者—消費者問題
第三篇:實驗報告五 生產者和消費者問題
第四篇:操作系統(tǒng)課程設計生產者消費者
第五篇:生產者與消費者的問題-----操作系統(tǒng)課程設計