資源簡介
(1)創建生產者和消費者線程
在Windows2000環境下,創建一個控制臺進程,在此進程中創建n個線程來模擬生產者或者消費者。這些線程的信息由本程序定義的“測試用例文件”中予以指定。
該文件的格式和含義如下:
3
1 P 3
2 P 4
3 C 4 1
4 P 2
5 C 3 1 2 4
第一行說明程序中設置幾個臨界區,其余每行分別描述了一個生產者或者消費者線程的信息。每一行的各字段間用Tab鍵隔開。不管是消費者還是生產者,都有一個對應的線程號,即每一行開始字段那個整數。第二個字段用字母P或者C區分是生產者還是消費者。第三個字段表示在進入相應線程后,在進行生產和消費動作前的休眠時間,以秒計時;這樣做的目的是可以通過調整這一列參數,控制開始進行生產和消費動作的時間。如果是代表生產者,則該行只有三個字段。如果代表消費者,則該行后邊還有若干字段,代表要求消費的產品所對應的生產者的線程號。所以務必確認這些對應的線程號存在并且該線程代表一個生產者。
(2)生產和消費的規則
在按照上述要求創建線程進行相應的讀寫操作時,還需要符合以下要求:
①共享緩沖區存在空閑空間時,生產者即可使用共享緩沖區。
②從上邊的測試數據文件例子可以看出,某一生產者生產一個產品后,可能不止一個消費者,或者一個消費者多次地請求消費該產品。此時,只有當所有的消費需求都被滿足以后,該產品所在的共享緩沖區才可以被釋放,并作為空閑空間允許新的生產者使用。
③每個消費者線程的各個消費需求之間存在先后順序。例如上述測試用例文件包含一行信息“5 C 3 l 2 4”,可知這代表一個消費者線程,該線程請求消費1,2,4號生產者線程生產的產品。而這種消費是有嚴格順序的,消費1號線程產品的請求得到滿足后才能繼續往下請求2號生產者線程的產品。
④要求在每個線程發出讀寫操作申請、開始讀寫操作和結束讀寫操作時分別顯示提示信息。
(3)相關基礎知識
本實驗所使用的生產者和消費者模型具有如下特點:
本實驗的多個緩沖區不是環形循環的,也不要求按順序訪問。生產者可以把產品放到目前某一個空緩沖區中。
消費者只消費指定生產者的產品。
在測試用例文件中指定了所有的生產和消費的需求,只有當共享緩沖區的數據滿足了所有關于它的消費需求后,此共享緩沖區才可以作為空閑空間允許新的生產者使用。
本實驗在為生產者分配緩沖區時各生產者間必須互斥,此后各個生產者的具體生產活動可以并發。而消費者之間只有在對同一產品進行消費時才需要互斥,同時它們在消費過程結束時需要判斷該消費對象是否已經消費完畢并清除該產品。
Windows用來實現同步和互斥的實體。在Windows中,常見的同步對象有:信號量(Semaphore)、互斥量(Mutex)、臨界段(CriticalSection)等。使用這些對象都分為三個步驟,一是創建或者初始化:接著請求該同步對象,隨即進入臨界區,這一步對應于互斥量的上鎖;最后釋放該同步對象,這對應于互斥量的解鎖。這些同步對象在一個線程中創建,在其他線程中都可以使用,從而實現同步互斥。

代碼片段和文件信息
#include?
#include
#include
#include
#include
const?int?max_linjiequ_num=77;?????
const?int?max_thread_num=88;????????
struct?thread??????
{
int?flag;?????????????????????????????????//標記進程是否已執行
int?num;?????????????????????????????????//進程號
char?p_c;????????????????????????????????
int?time;????????????????????????????????//進程等待時間
int?thread_request[max_thread_num];??????
int?request_num;?????????????????????????
};
struct?linjiequ?????
{
int?biaoji;?????//用以標記臨界區狀態,-1表示該緩沖區為空,1表該緩沖區將被生產者進程使用
int?p_num;??????
};
linjiequ?linjiequ[max_linjiequ_num];????//用該數組模擬緩沖區序列
thread?thread[max_thread_num];??????
int?thread_num;????????????????????//實際進程數
int?linjiequ_num;??????????????????
int?findposition()?????????
{
int?n;int?mutex;?????????????????????????//模擬互斥信號量
for(int?i=0;i {
if(linjiequ[i].biaoji==-1)
{
n=i;
linjiequ[i].biaoji=1;??
break;
}
}
return?n;
}
bool?otherrequest(int?n)?????????//判斷是否還有對同一產品的消費請求未執行
{
for(int?i=0;i for(int?j=0;j {
if(thread[i].thread_request[j]==n)
return?true;
break;
}
return?false;
}
int?little()
{
int?f=0;
while(thread[f].flag==1)
{
f++;
}
int?a=fl=thread[f].time;
for(int?w=0;w {
if(thread[w].time {
l=thread[w].time;
a=w;
}
}
return?a;
}
void?produce()
{
int?m=findposition();
Sleep(thread[little()].time*1000);
cout< thread[little()].flag=1;
}
void?consumer()
{
int?l=thread[little()].request_num;
for(int?i=0;i<=l;i++)
{
if(i {
int?temp=thread[little()].thread_request[i]-1;
if(thread[temp].flag==1)
{
cout< if(!otherrequest(temp+1))
{
cout<<“已無其他消費者消費“< for(int?j=0;j {
if(linjiequ[j].p_num==temp+1)
{
linjiequ[j].biaoji=-1;
cout< }
}
}
}
else
{
cout< thread[little()].time++;
i=l+1;
}
}
else
thread[little()].flag=1;
}
}
void?main()
{
//初始化緩沖區
for(int?i=0;i {
linjiequ[i].biaoji=-1;
}
//初始化線程請求隊列,及請求進程的個數
for(int?m=0;m {
for(int?n=0;n thread[m].thread_request[n]=-1;
thread[m].request_num=0;??????????????????//初始化請求進程的個數
thread[m].flag=0;
}
thread_num=5;
linjiequ_num=3;
thread[0].num=1;
thread[0].p_c=‘p‘;
thread[0].time=3;
thread[1].num=2;
thread[1].p_c=‘p‘;
thread[1].time?=4;
thread[2].num=3;
thread[2].p_c=‘c‘;
thread[2].time=4;
thread[2].thread_request[
?屬性????????????大小?????日期????時間???名稱
-----------?---------??----------?-----??----
?????目錄???????????0??2011-06-21?11:32??生產者與消費者\
?????目錄???????????0??2011-06-21?10:12??生產者與消費者\Debug\
?????文件??????209015??2011-06-21?10:12??生產者與消費者\Debug\p_c.exe
?????文件??????241212??2011-06-21?10:12??生產者與消費者\Debug\p_c.ilk
?????文件???????24080??2011-06-21?10:12??生產者與消費者\Debug\p_c.obj
?????文件?????3621252??2011-06-20?17:08??生產者與消費者\Debug\p_c.pch
?????文件?????1082368??2011-06-21?10:12??生產者與消費者\Debug\p_c.pdb
?????文件??????197632??2011-06-21?10:50??生產者與消費者\Debug\vc60.idb
?????文件??????143360??2011-06-21?10:12??生產者與消費者\Debug\vc60.pdb
?????文件????????4380??2008-12-14?20:52??生產者與消費者\produce_consume.dsp
?????文件?????????538??2008-12-14?20:52??生產者與消費者\produce_consume.dsw
?????文件???????50176??2011-06-20?16:37??生產者與消費者\produce_consume.ncb
?????文件???????48640??2011-06-20?16:37??生產者與消費者\produce_consume.opt
?????文件?????????921??2008-12-14?21:10??生產者與消費者\produce_consume.plg
?????文件????????4411??2011-06-21?10:12??生產者與消費者\p_c.cpp
?????文件????????3365??2011-06-21?08:47??生產者與消費者\p_c.dsp
?????文件?????????514??2011-06-21?11:32??生產者與消費者\p_c.dsw
?????文件???????50176??2011-06-21?11:32??生產者與消費者\p_c.ncb
?????文件???????48640??2011-06-21?11:32??生產者與消費者\p_c.opt
?????文件?????????240??2011-06-21?10:50??生產者與消費者\p_c.plg
評論
共有 條評論