




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、齊齊哈爾大學(xué)操作系統(tǒng)課程綜合實(shí)踐題目:多進(jìn)程同步方法解決生產(chǎn)者消費(fèi)者問題班級:0姓名:0 學(xué)號:0指導(dǎo)教師:0 2011年12 月7日綜合實(shí)踐評分表班級0姓名0指導(dǎo)教師0題目:多進(jìn)程同步方法解決生產(chǎn)者消費(fèi)者問題 評分標(biāo)準(zhǔn)評分標(biāo)準(zhǔn)分?jǐn)?shù)權(quán)重評分的依據(jù)得分AC選題10選題符合大綱要求,題目較新穎,工作量大選題基本符合大綱要求,工作量適中工作態(tài)度10態(tài)度端正,能主動認(rèn)真完成各個環(huán)節(jié)的工作,不遲到早退,出勤好。能夠完成各環(huán)節(jié)基本工作,出勤較好。存儲結(jié)構(gòu)、算法描述20能正確選擇存儲結(jié)構(gòu),定義準(zhǔn)確,算法流程圖或類C語言描述的算法準(zhǔn)確無誤能正確選擇存儲結(jié)構(gòu),算法流程圖或類C語言描述的算法基本準(zhǔn)確獨(dú)立解決問題的
2、能力10具有獨(dú)立分析、解決問題能力,有一定的創(chuàng)造性,能夠獨(dú)立完成軟件的設(shè)計與調(diào)試工作,程序結(jié)構(gòu)清晰,邏輯嚴(yán)謹(jǐn),功能完善。有一定的分析、解決問題能力。能夠在老師指導(dǎo)下完成軟件的設(shè)計與調(diào)試工作,程序功能較完善。答辨問題回答20能準(zhǔn)確回答老師提出的問題能基本準(zhǔn)確回答老師提出的問題程序運(yùn)行情況10程序運(yùn)行正確、界面清晰,測試數(shù)據(jù)設(shè)計合理。程序運(yùn)行正確、界面較清晰,能給出合適的測試數(shù)據(jù)。綜合實(shí)踐報告20格式規(guī)范,層次清晰,設(shè)計思想明確,解決問題方法合理,體會深刻。格式較規(guī)范,設(shè)計思想基本明確,解決問題方法較合理??偡种笇?dǎo)教師(簽字): 注:介于A和C之間為B級,低于C為D級和E級。按各項指標(biāo)打分后,總分
3、在90100為優(yōu),8089為良,7079為中,6069為及格,60分以下為不及格。多進(jìn)程同步方法解決生產(chǎn)者消費(fèi)者問題摘要:本文論述了多進(jìn)程同步方法解決生產(chǎn)者消費(fèi)者問題的過程。該程序使學(xué)生對操作系統(tǒng)的工作機(jī)制有了初步的了解,其主要目的是使學(xué)生了解和撐握在Linux系統(tǒng)平臺下的C語言編程,用來解決實(shí)現(xiàn)生活中遇到的問題。并以Linux系統(tǒng)開發(fā)平臺,以及虛擬機(jī)來實(shí)現(xiàn)。關(guān)鍵字:生產(chǎn)者消費(fèi)者問題,Linux系統(tǒng)平臺,虛擬機(jī),信號量,線程(thread)多進(jìn)程同步方法解決生產(chǎn)者消費(fèi)者問題一、課程設(shè)計所需設(shè)備計算機(jī)一臺,Red Hat linux9.03系統(tǒng)一套。二、課程設(shè)計預(yù)期目的通過研究Linux 的進(jìn)程
4、機(jī)制和信號量實(shí)現(xiàn)生產(chǎn)者消費(fèi)者問題的并發(fā)控制。三、課程設(shè)計任務(wù)用多進(jìn)程同步方法解決生產(chǎn)者-消費(fèi)者問題設(shè)計目的:通過研究Linux 的進(jìn)程機(jī)制和信號量實(shí)現(xiàn)生產(chǎn)者消費(fèi)者問題的并發(fā)控制.說明:有界緩沖區(qū)內(nèi)設(shè)有20個存儲單元,放入/取出的數(shù)據(jù)項設(shè)定為1-20這20個整型數(shù).設(shè)計要求:1) 每個生產(chǎn)者和消費(fèi)者對有界緩沖區(qū)進(jìn)行操作后,即時顯示有界緩沖區(qū)的全部內(nèi)容,當(dāng)前指針位置和生產(chǎn)者/消費(fèi)者線程的標(biāo)識符.2) 生產(chǎn)者和消費(fèi)者各有兩個以上.3) 多個生產(chǎn)者或多個消費(fèi)者之間須有共享對緩沖區(qū)進(jìn)行操作的函數(shù)代碼.四、課程設(shè)計基本思想多進(jìn)程是一種非常簡潔的多任務(wù)操作方式。在Linux系統(tǒng)下,啟動一個新的進(jìn)程必須分配給
5、它獨(dú)立的地址空間,建立眾多的數(shù)據(jù)表來維護(hù)它的代碼段、堆棧段和數(shù)據(jù)段,這是一種煩瑣的多任務(wù)工作方式。生產(chǎn)者-消費(fèi)者方案是多進(jìn)程應(yīng)用程序開發(fā)中最常用的構(gòu)造之一。因此困難也在于此。因?yàn)樵谝粋€應(yīng)用程序中可以多次重復(fù)生產(chǎn)者-消費(fèi)者行為,其代碼也可以如此。設(shè)計中創(chuàng)建了 Consumer 類,該類通過在一些多進(jìn)程應(yīng)用程序中促進(jìn)代碼重用以及簡化代碼調(diào)試和維護(hù)來解決這個問題。多進(jìn)程應(yīng)用程序通常利用生產(chǎn)者-消費(fèi)者編程方案,其中由生產(chǎn)者進(jìn)程創(chuàng)建重復(fù)性作業(yè),將其傳遞給作業(yè)隊列,然后由消費(fèi)者進(jìn)程處理作業(yè)。多進(jìn)程是一種使應(yīng)用程序能同時處理多個操作的編程技術(shù)。通常有兩種不同類型的多進(jìn)程操作使用多個進(jìn)程:適時事件,當(dāng)作業(yè)必須
6、在特定的時間或在特定的間隔內(nèi)調(diào)度執(zhí)行時;后臺處理,當(dāng)后臺事件必須與當(dāng)前執(zhí)行流并行處理或執(zhí)行時;適時事件的示例包括程序提醒、超時事件以及諸如輪詢和刷新之類的重復(fù)性操作。后臺處理的示例包括等待發(fā)送的包或等待處理的已接收的消息。生產(chǎn)者-消費(fèi)者方案很適合于后臺處理類別的情況。這些情況通常圍繞一個作業(yè)“生產(chǎn)者”方和一個作業(yè)“消費(fèi)者”方。當(dāng)然,關(guān)于作業(yè)并行執(zhí)行還有其它考慮事項。在大多數(shù)情況下,對于使用同一資源的作業(yè),應(yīng)以FCFS的方式按順序處理,這可以通過使用單進(jìn)程的消費(fèi)者輕松實(shí)現(xiàn)。通過使用這種方法,使用單個進(jìn)程來訪問單個資源,而不是用多個進(jìn)程來訪問單個資源。要啟用標(biāo)準(zhǔn)消費(fèi)者,當(dāng)作業(yè)到來時創(chuàng)建一個作業(yè)隊列
7、來存儲所有作業(yè)。生產(chǎn)者進(jìn)程通過將新對象添加到消費(fèi)者隊列來交付這個要處理的新對象。然后消費(fèi)者進(jìn)程從隊列取出每個對象,并依次處理。當(dāng)隊列為空時,消費(fèi)者進(jìn)入休眠。當(dāng)新的對象添加到空隊列時,消費(fèi)者會醒來并處理該對象。五詳細(xì)設(shè)計5.1、調(diào)試問題分析為解決生產(chǎn)者/消費(fèi)者問題,應(yīng)該設(shè)置兩個資源信號量,其中一個表示空緩沖區(qū)的數(shù)目,用Full表示,其初始值為有界緩沖區(qū)的大小BUFFER_NUM;另一個表示緩沖區(qū)中產(chǎn)品的數(shù)目,用Empty表示,其初始值為0。另外,由于有界緩沖區(qū)是一個臨界資源,必須互斥使用,所以還需要再設(shè)置一個互斥信號量Mutex,起初值為1。 在生產(chǎn)者/消費(fèi)者問題中,信號量實(shí)現(xiàn)兩種功能。首先,它
8、是生產(chǎn)產(chǎn)品和消費(fèi)產(chǎn)品的計數(shù)器,計數(shù)器的初始值是可利用的資源數(shù)目(有界緩沖區(qū)的長度)。其次,它是確保產(chǎn)品的生產(chǎn)者和消費(fèi)者之間動作同步的同步器。 生產(chǎn)者要生產(chǎn)一個產(chǎn)品時,首先對資源信號量Full和互斥信號量Mutex進(jìn)行P操作,申請資源。如果可以通過的話,就生產(chǎn)一個產(chǎn)品,并把產(chǎn)品送入緩沖區(qū)。然后對互斥信號量Mutex和資源信號量Empty進(jìn)行V操作,釋放資源。 消費(fèi)者要消費(fèi)一個產(chǎn)品時,首先對資源信號量Empty和互斥信號量Mutex進(jìn)行P操作,申請資源。如果可以通過的話,就從緩沖區(qū)取出一個產(chǎn)品并消費(fèi)掉。然后對互斥信號量Mutex和資源信號量Full進(jìn)行V操作,釋放資源。如果緩沖區(qū)中已經(jīng)沒有可用資源
9、,就把申請資源的進(jìn)程添加到等待隊列的隊尾。如果有一個資源被釋放,在等待隊列中的第一個進(jìn)程被喚醒并取得這個資源的使用權(quán)。 5.2、程序流程圖生產(chǎn)者線程開始資源信號量P操作互斥信號量P操作生產(chǎn)一個產(chǎn)品把產(chǎn)品送入緩沖區(qū)互斥信號量V操作資源信號量V操作等待隊列中有消費(fèi)者線程等待隊列中有消費(fèi)者線程線程自我阻塞添加到等待隊列線程自我阻塞添加到等待隊列未通過未通過通過通過喚醒對頭的消費(fèi)者線程喚醒對頭的消費(fèi)者線程生產(chǎn)者線程結(jié)束YYNN圖一 生產(chǎn)者流程結(jié)構(gòu)消費(fèi)者線程開始資源信號量P操作互斥信號量P操作從緩沖區(qū)取出一個產(chǎn)品消費(fèi)一個產(chǎn)品互斥信號量V操作資源信號量V操作等待隊列中有生產(chǎn)者線程等待隊列中有生產(chǎn)者線程線程
10、自我阻塞添加到等待隊列線程自我阻塞添加到等待隊列未通過未通過通過通過喚醒對頭的生產(chǎn)者線程喚醒對頭的生產(chǎn)者線程消費(fèi)者線程結(jié)束YYNN圖二 消費(fèi)者流程結(jié)構(gòu)5.3、程序自定義函數(shù)1、void produce(struct sem_info * );這個函數(shù)是生產(chǎn)者進(jìn)行的生產(chǎn)過程,為所有的生產(chǎn)者所共享。結(jié)構(gòu)體指針用來接收生產(chǎn)者線程創(chuàng)建時傳來的生產(chǎn)者的個人信息。2、void consumer(struct sem_info * );這個函數(shù)是消費(fèi)者進(jìn)行的生產(chǎn)過程,為所有的消費(fèi)者所共享。結(jié)構(gòu)體指針用來接收消費(fèi)者線程創(chuàng)建時傳來的消費(fèi)者的個人信息。3、void setproduce(void); 這個函數(shù)是用
11、來設(shè)置生產(chǎn)者的個數(shù)和他們的名字。4、void setconsumer(void);這個函數(shù)是用來設(shè)置消費(fèi)者的個數(shù)和他們的名字。5、void activepthread(int);這個函數(shù)是用來創(chuàng)建生產(chǎn)者線程,int型參數(shù)為生產(chǎn)者的個數(shù)。6、void activecthread(int);這個函數(shù)是用來創(chuàng)建生產(chǎn)者線程,int型參數(shù)為生產(chǎn)者的個數(shù)。7、int gettime(void);這個函數(shù)返回來一個整數(shù),作為線程的sleep()函數(shù)的參數(shù)。8、void myscanf(void);這個函數(shù)用來獲取設(shè)置生產(chǎn)者和消費(fèi)者的個數(shù)時的整數(shù),確保這個數(shù)字在0到MAX_BUFFER之間。5.4、系統(tǒng)函數(shù)調(diào)
12、用線程Linux系統(tǒng)下的多線程遵循POSIX線程接口,稱為pthread。編寫Linux下的多線程程序,需要使用頭文件pthread.h,連接時需要使用庫libpthread.a。Linux下pthread的實(shí)現(xiàn)是通過系統(tǒng)調(diào)用clone()來實(shí)現(xiàn)的。clone()是Linux所特有的系統(tǒng)調(diào)用,它的使用方式類似fork。函數(shù)pthread_create用來創(chuàng)建一個線程,它的原型為:extern int pthread_create _P (pthread_t *_thread, _const pthread_attr_t *_attr,void *(*_start_routine) (void
13、*), void *_arg);第一個參數(shù)為指向線程標(biāo)識符的指針,第二個參數(shù)用來設(shè)置線程屬性,第三個參數(shù)是線程運(yùn)行函數(shù)的起始地址,最后一個參數(shù)是運(yùn)行函數(shù)的參數(shù)。第二個參數(shù)我們也設(shè)為空指針,這樣將生成默認(rèn)屬性的線程。當(dāng)創(chuàng)建線程成功時,函數(shù)返回0,若不為0則說明創(chuàng)建線程失敗,常見的錯誤返回代碼為EAGAIN和EINVAL。前者表示系統(tǒng)限制創(chuàng)建新的線程,例如線程數(shù)目過多了;后者表示第二個參數(shù)代表的線程屬性值非法。創(chuàng)建線程成功后,新創(chuàng)建的線程則運(yùn)行參數(shù)三和參數(shù)四確定的函數(shù),原來的線程則繼續(xù)運(yùn)行下一行代碼。函數(shù)pthread_join用來等待一個線程的結(jié)束。函數(shù)原型為:extern int pthrea
14、d_join _P (pthread_t _th, void *_thread_return);第一個參數(shù)為被等待的線程標(biāo)識符,第二個參數(shù)為一個用戶定義的指針,它可以用來存儲被等待線程的返回值。這個函數(shù)是一個線程阻塞的函數(shù),調(diào)用它的函數(shù)將一直等待到被等待的線程結(jié)束為止,當(dāng)函數(shù)返回時,被等待線程的資源被收回。一個線程的結(jié)束有兩種途徑,一種是函數(shù)結(jié)束了,調(diào)用它的線程也就結(jié)束了;另一種方式是通過函數(shù)pthread_exit來實(shí)現(xiàn)。它的函數(shù)原型為:extern void pthread_exit _P (void *_retval) _attribute_ (_noreturn_);唯一的參數(shù)是函數(shù)的
15、返回代碼,只要pthread_join中的第二個參數(shù)thread_return不是NULL,這個值將被傳遞給 thread_return。最后要說明的是,一個線程不能被多個線程等待,否則第一個接收到信號的線程成功返回,其余調(diào)用pthread_join的線程則返回錯誤代碼ESRCH。信號量信號量本質(zhì)上是一個非負(fù)的整數(shù)計數(shù)器,它被用來控制對公共資源的訪問。當(dāng)公共資源增加時,調(diào)用函數(shù)sem_post()增加信號量。只有當(dāng)信號量值大于時,才能使用公共資源,使用后,函數(shù)sem_wait()減少信號量。函數(shù)sem_trywait()和函數(shù)pthread_ mutex_trylock()起同樣的作用,它是函
16、數(shù)sem_wait()的非阻塞版本。它們都在頭文件 /usr/include/semaphore.h中定義。信號量的數(shù)據(jù)類型為結(jié)構(gòu)sem_t,它本質(zhì)上是一個長整型的數(shù)。函數(shù)sem_init()用來初始化一個信號量。它的原型為:extern int sem_init _P (sem_t *_sem, int _pshared, unsigned int _value);sem為指向信號量結(jié)構(gòu)的一個指針;pshared不為時此信號量在進(jìn)程間共享,否則只能為當(dāng)前進(jìn)程的所有線程共享;value給出了信號量的初始值。函數(shù)sem_post( sem_t *sem )用來增加信號量的值。當(dāng)有線程阻塞在這個信
17、號量上時,調(diào)用這個函數(shù)會使其中的一個線程不在阻塞,選擇機(jī)制同樣是由線程的調(diào)度策略決定的。函數(shù)sem_wait( sem_t *sem )被用來阻塞當(dāng)前線程直到信號量sem的值大于0,解除阻塞后將sem的值減一,表明公共資源經(jīng)使用后減少。函數(shù)sem_trywait ( sem_t *sem )是函數(shù)sem_wait()的非阻塞版本,它直接將信號量sem的值減一。函數(shù)sem_destroy(sem_t *sem)用來釋放信號量sem。六源程序清單6.1、源程序#include <windows.h> #include <stdio.h> #include <stdli
18、b.h> #include <time.h> typedef HANDLE Semaphore; / 信號量的Windows原型 #define P(S) WaitForSingleObject(S,INFINITE) / 定義Windows下的P操作 #define V(S) ReleaseSemaphore(S,1,NULL) / 定義Windows下的V操作 #define rate 1000 #define CONSUMER_NUM 2 /* 消費(fèi)者個數(shù) */ #define PRODUCER_NUM 3 /* 生產(chǎn)者個數(shù) */ #define BUFFER_NUM
19、20 /* 緩沖區(qū)個數(shù) */ char *thing8 = "雞腿堡", "薯條", "可樂", "三明治", "面包", "小籠包", "火腿","饅頭" /生產(chǎn)和消費(fèi)的產(chǎn)品名稱 struct Buffer int productBUFFER_NUM; / 緩沖區(qū) int start,end; / 兩個指針相當(dāng)于教材中的 in out 指針 g_buf; Semaphore Empty,Full,Mutex; /分別相當(dāng)于Empty,
20、 Full, Mutex三個信號量 /* 消費(fèi)者線程*/ DWORD WINAPI Consumer(LPVOID para) / i表示第i個消費(fèi)者 int i = *(int *)para; /利用para傳入當(dāng)前消費(fèi)者的編號 int ptr; / 待消費(fèi)的內(nèi)容的指針 printf("消費(fèi)者%1d: 需要資源n", i); int j=0; while (j+<4) / 等待產(chǎn)品 P(Full); / 有產(chǎn)品,先鎖住緩沖區(qū) P(Mutex); / 記錄消費(fèi)的物品 ptr=g_buf.start; / 再移動緩沖區(qū)指針 g_buf.start= (g_buf.sta
21、rt+1)%BUFFER_NUM; /讓其他消費(fèi)者或生產(chǎn)者使用 printf(" 消費(fèi)者%01d: 我需要buf%d=%sn",i, ptr, thingg_ductptr); /消費(fèi)完畢,并釋放一個緩沖 printf(" 消費(fèi)者%01d: 我消費(fèi)完畢%sn", i,thingg_ductptr); V(Mutex); V(Empty); Sleep(rate*rand()%10+110); return 0; /* 生產(chǎn)者線程*/ DWORD WINAPI Producer(LPVOID para) int i = *(in
22、t *)para - CONSUMER_NUM; int ptr; int data; /產(chǎn)品 int j=0; while(j+<4) data=rand()%8; printf("生產(chǎn)者%01d: 生產(chǎn)出: %s!n",i,thingdata); /等待存放空間 P(Empty); /有地方,先鎖住緩沖區(qū) P(Mutex); /記錄消費(fèi)的物品 ptr=g_buf.end; /再移動緩沖區(qū)指針 g_buf.end =(g_buf.end+1)%BUFFER_NUM; printf("生產(chǎn)者%01d: 放到緩沖區(qū) buf%d=%sn",i,ptr,
23、thingdata); g_ductptr=data; /放好了完畢,釋放一個產(chǎn)品 /讓其他消費(fèi)者或生產(chǎn)者使用 V(Mutex); V(Full); Sleep(rate/2*rand()%10+110); return 0; int main(int argc,char *argv) /線程技術(shù),前面為消費(fèi)者線程,后面為生產(chǎn)者線程 HANDLE hThreadCONSUMER_NUM+PRODUCER_NUM; / 線程計數(shù) srand(time(NULL); rand(); DWORD tid; int i=0; /初始化信號量 Mutex=CreateSemaphore(N
24、ULL,1,1,"MutexOfConsumerAndProducer"); Empty=CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, "BufferSemaphone"); Full=CreateSemaphore(NULL,0,BUFFER_NUM,"ProductSemaphone"); if(!Empty|!Full|!Mutex) printf("Create Semaphone Error!n"); return -1; int totalThreads=C
25、ONSUMER_NUM+PRODUCER_NUM; /開啟消費(fèi)者線程 printf("先請消費(fèi)者上席!n"); for(i=0;i<CONSUMER_NUM; i+) hThreadi=CreateThread(NULL, 0, Consumer, &i,0,&tid); if(hThreadi)WaitForSingleObject(hThreadi,10); printf("生產(chǎn)者就位!n"); for(;i<totalThreads;i+) hThreadi=CreateThread(NULL,0,Producer,&i,0,&tid); if(hThreadi)WaitForSingleObject(hThreadi,10); /生產(chǎn)者和消費(fèi)者的執(zhí)行 WaitForMultipleObjects(totalThreads,hThread,TRUE,INFINITE); return 0; 6.2、編譯及運(yùn)行結(jié)果在程序中設(shè)置了兩個消費(fèi)者,三個生產(chǎn)者,為便于描述出生產(chǎn)-消費(fèi)的
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 湘潭一中面試題庫及答案
- 中級社會工作者的社會適應(yīng)能力培養(yǎng)試題及答案
- 系統(tǒng)集成認(rèn)證考試經(jīng)驗(yàn)總結(jié)試題及答案
- 共享客服面試題及答案
- 2025年軟件評測師考試知識點(diǎn)及試題與答案
- 快速掌握軟件評測師試題及答案技巧
- 淮安市初三五校聯(lián)考試題及答案
- 2025年噴霧通風(fēng)冷卻塔項目立項申請報告模范
- 2025年軟件評測師考試有效復(fù)習(xí)與提升策略試題及答案
- 系統(tǒng)分析師考試趨勢解析試題及答案
- 迪奧品牌分析通用PPT課件
- 高迪圣家族大教堂賞析(課堂PPT)
- 小天鵝說明書
- 四川危險廢物經(jīng)營許可證申請書
- 吊具與索具點(diǎn)檢表
- microRNA研究 ppt課件
- 加油站安全隱患排查檢查表
- 品牌策略營銷課件(共105頁).ppt
- 單片機(jī)課件第8章存儲器的擴(kuò)展
- Photoshop圖像處理模擬試卷1
- 英文版簡易-電商送貨單-產(chǎn)品隨行單模板
評論
0/150
提交評論