北郵操作系統(tǒng)消費(fèi)者與生產(chǎn)者實(shí)驗(yàn)報(bào)告_第1頁(yè)
北郵操作系統(tǒng)消費(fèi)者與生產(chǎn)者實(shí)驗(yàn)報(bào)告_第2頁(yè)
北郵操作系統(tǒng)消費(fèi)者與生產(chǎn)者實(shí)驗(yàn)報(bào)告_第3頁(yè)
北郵操作系統(tǒng)消費(fèi)者與生產(chǎn)者實(shí)驗(yàn)報(bào)告_第4頁(yè)
北郵操作系統(tǒng)消費(fèi)者與生產(chǎn)者實(shí)驗(yàn)報(bào)告_第5頁(yè)
已閱讀5頁(yè),還剩5頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、 操作系統(tǒng)實(shí)驗(yàn)課程報(bào)告 課題: 消費(fèi)者與生產(chǎn)者實(shí)驗(yàn)姓 名 張濤 學(xué) 院 計(jì)算機(jī)學(xué)院 班 級(jí) 2011211311 學(xué) 號(hào) 2011211419 2013年 12月 14日1實(shí)驗(yàn)?zāi)康模?)理解線程同步的思想和方法,學(xué)會(huì)用線程同步解決臨界區(qū)問(wèn)題,本次實(shí)驗(yàn)解決生產(chǎn)者消費(fèi)者問(wèn)題2了解windows系統(tǒng)或linux系統(tǒng)下中信號(hào)量的使用方法。2實(shí)驗(yàn)預(yù)備內(nèi)容(1) 閱讀Linux的sched.h源碼文件,加深對(duì)進(jìn)程管理概念的理解。這個(gè)文件長(zhǎng)達(dá)2616行,這里截取第12211548行抄錄在實(shí)驗(yàn)報(bào)告最后,即結(jié)構(gòu)體task_struct,地位相當(dāng)于PCB。下面對(duì)幾個(gè)比較重要的參數(shù),結(jié)合本人的了解 以及 網(wǎng)上查閱的

2、資料 做一點(diǎn)解釋。中括號(hào)內(nèi)的數(shù)字為代碼行號(hào),下同。volatilelongstate:【1222】進(jìn)程狀態(tài)字,表示進(jìn)程當(dāng)前的狀態(tài)(運(yùn)行、就緒、等待、僵死、暫停、交換),分別對(duì)應(yīng)已定義好的常量;TASK_RUNING:正在運(yùn)行或可運(yùn)行狀態(tài);TASK_INTERRUPTIBLE:可打斷睡眠狀態(tài);TASK_UNINTERRUPTIBLE:不可打斷睡眠狀態(tài);TASK_ZOMBLE:僵死狀態(tài);TASK_STOPPED:暫停狀態(tài);交換狀態(tài)。void*stack:【1223】進(jìn)程所使用的棧空間;unsignedintflags:【1225】進(jìn)程標(biāo)志(創(chuàng)建、關(guān)閉、跟蹤、被跟蹤、內(nèi)核dump等),同樣對(duì)應(yīng)已定義

3、好的常量;unsignedintrt_priority:【1237】表示本進(jìn)程的實(shí)時(shí)優(yōu)先級(jí);conststructsched_class *sched_class、structsched_entity se:【1239,1240】分別是調(diào)度類和調(diào)度實(shí)體,這兩個(gè)結(jié)構(gòu)包含了用于任務(wù)調(diào)度的完整的信息(進(jìn)程信息、調(diào)度策略等);unsignedintpolicy:【1260】進(jìn)程的調(diào)度策略標(biāo)志,有三種調(diào)度標(biāo)志:SCHED_OTHER:普通進(jìn)程的調(diào)度策略,基于優(yōu)先權(quán)的輪轉(zhuǎn)法;SCHED_FIFO:實(shí)時(shí)進(jìn)程的調(diào)度策略,基于先進(jìn)先出的算法;SCHED_RR:實(shí)時(shí)進(jìn)程的調(diào)度策略,基于優(yōu)先權(quán)的輪詢法。struct

4、list_head tasks:【1274】任務(wù)隊(duì)列,為一雙向循環(huán)鏈表;intpdeath_signal:【1282】父進(jìn)程終止時(shí)產(chǎn)生的信號(hào);pid_t pid:【1294】進(jìn)程標(biāo)識(shí)符,操作系統(tǒng)每創(chuàng)建一個(gè)新的進(jìn)程就要為這個(gè)新進(jìn)程分配一個(gè)進(jìn)程控制塊(PCB),系統(tǒng)內(nèi)核通過(guò)pid區(qū)分這些進(jìn)程的;structtask_struct *real_parent:【1307】本進(jìn)程的父進(jìn)程的PCB;structlist_head children:【1312】本進(jìn)程的子進(jìn)程列表;structlist_head ptraced:【1321】本進(jìn)程正在使用ptrace監(jiān)視的進(jìn)程列表;structthread_

5、struct thread:【1375】本進(jìn)程下屬的線程集;structsignal_struct *signal、structsighand_struct *sighand:【1383,1384】分別是進(jìn)程運(yùn)行時(shí)產(chǎn)生的信號(hào)以及信號(hào)處理模塊。(2) 閱讀Linux的pthread.h源碼文件,分析線程的創(chuàng)建過(guò)程。pthread接口說(shuō)明#include 1、創(chuàng)建int pthread_create( pthread_t *tid, const pthread_attr_t *attr, void *(* func) (void *), void *arg );attr: 線程屬性包括:優(yōu)先級(jí)、初

6、始棧大小,是否應(yīng)該成為一個(gè)守護(hù)線程。缺省設(shè)置,NULL后面是線程要執(zhí)行的函數(shù)和參數(shù)成功返回 02、等待一個(gè)給定線程終止int pthread_join( pthread_t tid, void *status);等待線程結(jié)束 critiction 可以在進(jìn)程中使用,mutex只可在進(jìn)程中使用statues返回等待線程的返回值 multiple definition of _dso_handle/usr/lib/gcc/i486-linux-gnu/4.4.3/crtbegin.o:(.data+0x0): first defined herethreadTest: In function _i

7、nit:(.init+0x0): multiple definition of _init/usr/lib/gcc/i486-linux-gnu/4.4.3/././././lib/crti.o:(.init+0x0): first defined here/tmp/cchm2SmY.o:(.data+0x0): multiple definition of flagthreadTest:(.data+0x8): first defined here/tmp/cchm2SmY.o: In function threadMe3、得到自身的pidpthread_t pthread_self(voi

8、d);4、pthread_detach函數(shù)int pthread_detach( pthread_t pid );把指定的線程轉(zhuǎn)變?yōu)槊撾x狀態(tài)一個(gè)線程或者是可匯合的(joinable,缺省值),或者是脫離的(detached)。當(dāng)一個(gè)可匯合的線程終止時(shí),它的線程ID和退出狀態(tài)將留到另一個(gè)線程對(duì)它調(diào)用pthread_join。脫離線程卻象守護(hù)進(jìn)程:當(dāng)它們終止的時(shí),所有相關(guān)資源都被釋放,我們不能等待它們終止。如果一個(gè)線程需要知道另一個(gè)線程什么時(shí)候終止,那就最好好吃第二個(gè)線程的可匯合狀態(tài)。本函數(shù)通常由想讓自己脫離的線程調(diào)用,如下語(yǔ)句pthread_detach( pthread_self() );5、

9、終止一個(gè)線程void pthread_exit( void *statue );指針sttus不能指向局部于調(diào)用對(duì)象,因?yàn)榫€程終止時(shí)這樣的對(duì)象也消失(3) 閱讀Linux的semaphore.h源碼文件,分析線程的創(chuàng)建過(guò)程。typedef struct sem_t_ * sem_t;PTW32_DLLPORT int _cdecl sem_init (sem_t * sem, int pshared, unsigned int value);PTW32_DLLPORT int _cdecl sem_destroy (sem_t * sem);PTW32_DLLPORT int _cdecl s

10、em_trywait (sem_t * sem);PTW32_DLLPORT int _cdecl sem_wait (sem_t * sem);PTW32_DLLPORT int _cdecl sem_post (sem_t * sem);PTW32_DLLPORT int _cdecl sem_post_multiple (sem_t * sem, int count);PTW32_DLLPORT int _cdecl sem_close (sem_t * sem);PTW32_DLLPORT int _cdecl sem_unlink (const char * name);int se

11、m_init(sem_t *sem,int pshared,unsigned int value)。用于信號(hào)量的初始化,第一個(gè)參數(shù)為信號(hào)量的名稱,第二個(gè)參數(shù)為信號(hào)量的共享屬性,一般設(shè)為0(不共享),第三個(gè)參數(shù)為信號(hào)量的初始值。int sem_wait(sem_t *sem)。相當(dāng)于上面的wait()操作,作用是當(dāng)信號(hào)量的值大于0時(shí),給信號(hào)量的值減1,否則會(huì)阻塞直至信號(hào)量的值大于0。它是一個(gè)原子操作。int sem_post(sem_t *sem)。相當(dāng)于上面的signal()操作,作用是給信號(hào)量的值加1。它也是一個(gè)原子操作。*/3實(shí)驗(yàn)環(huán)境此實(shí)驗(yàn)采用的是Win8下Microsoft Visual

12、 Stdio 2012工程。由于系統(tǒng)不包含semaphore.h,sched.h及pthread.h頭文件,所以這些頭文件都是從網(wǎng)上FTP資源下載后,加入工程的。程序中加入#pragma comment(lib, pthreadVC2.lib)來(lái)調(diào)用pthread鏈接庫(kù)。文件根目錄下已下載pthreadVC2.dll*/4實(shí)驗(yàn)步驟A設(shè)計(jì)思路這個(gè)問(wèn)題是進(jìn)程同步的經(jīng)典問(wèn)題之一,基本思路是設(shè)置三個(gè)信號(hào)量:mutex信號(hào)量,用于控制生產(chǎn)者和消費(fèi)者對(duì)于緩沖區(qū)的互斥訪問(wèn);empty信號(hào)量,記錄當(dāng)前為空的緩沖區(qū)的數(shù)目,初始化為所有緩沖區(qū)的數(shù)目BUF_SIZE;full信號(hào)量,記錄當(dāng)前已滿的緩沖區(qū)的數(shù)目,初始

13、化為0。*/一個(gè)buffer,一個(gè)生產(chǎn)者,一個(gè)消費(fèi)者(1)規(guī)則只有buffer為空才能put;只有buffer中有數(shù)據(jù)才能get;不允許多個(gè)put操作同時(shí)進(jìn)行;不允許多個(gè)get操作同時(shí)進(jìn)行。這時(shí)buffer變成了臨界資源,消費(fèi)者之間需要互斥地使用,生產(chǎn)者之間也需要互斥地使用,消費(fèi)者和生產(chǎn)者之間也需要互斥地使用,這時(shí)設(shè)置兩個(gè)信號(hào)量s1,s2實(shí)現(xiàn)同步,例外設(shè)置S信號(hào),代表buffer這種臨界資源,用于互斥,稱之為互斥信號(hào)量。(2)實(shí)現(xiàn)流程p(s1)判斷buffer是否空p(s)是否可進(jìn)行put,是否有其他進(jìn)程占用bufferputv(s)釋放buffer,讓其他進(jìn)程可以使用v(s2)給消費(fèi)者進(jìn)程釋

14、放一個(gè)buffer中有數(shù)據(jù)的信號(hào)p(s2)判斷是否有數(shù)據(jù)p(s)是否可進(jìn)行g(shù)et,是否有其他進(jìn)程占用getv(s)釋放buffer,讓其他進(jìn)程可以使用v(s1)給生產(chǎn)者釋放一個(gè)buffer為空的信號(hào)通過(guò)3個(gè)信號(hào)量,實(shí)現(xiàn)了消費(fèi)者和生產(chǎn)者之間同步關(guān)系,也保證了在某個(gè)時(shí)刻只有一個(gè)進(jìn)程使用臨界資源buffer。生產(chǎn)者進(jìn)程的代碼結(jié)構(gòu)描述如下:while(true) nextp=produce();wait(empty);wait(mutex);put(nextp);signal(mutex);signal(full); 消費(fèi)者進(jìn)程的代碼結(jié)構(gòu)描述如下:while(true) wait(full);wait

15、(mutex);nextc=get();signal(mutex);signal(empty);consume(nextc); 這里兩個(gè)wait語(yǔ)句的次序并不能調(diào)換,這是因?yàn)槿绻麑蓚€(gè)wait操作即wait(full)和wait(mutex)互換位置,或者將release(mutex)與release(full)互換位置,當(dāng)緩沖區(qū)存滿產(chǎn)品時(shí),生產(chǎn)者又生產(chǎn)了一件產(chǎn)品,它欲向緩沖區(qū)存放時(shí)將在empty上等待,但它已經(jīng)占有了使用緩沖區(qū)的權(quán)利。這時(shí)消費(fèi)者要取產(chǎn)品時(shí)將停留在mutex上得不到使用緩沖區(qū)的權(quán)利,導(dǎo)致生產(chǎn)者等待消費(fèi)者取走產(chǎn)品,而消費(fèi)者卻在等待生產(chǎn)者釋放使用緩沖區(qū)的權(quán)利,這種相互等待永遠(yuǎn)結(jié)束不

16、了。因此進(jìn)程將會(huì)發(fā)生死鎖。*/B實(shí)驗(yàn)代碼分析生產(chǎn)者:/* Producer * Produce items and try to put it into the buffer* If the buffer is full, waiting* When produced, we output like that: Producer 2 produced 222* When successfully put, we output: Producer 2 have put product 222 into the buffer after 100 milliseconds* The millisec

17、onds is the timespan from the producer produced the item* When the buffer is full but the producer put the item, an error occurred* (No way it will happen.)*/#define PTIMESPANMAX 5000void* producer(void* params) int id=*(int *)params; while(true) SLEEP(rand()%PTIMESPANMAX); buffer_item rnd=rand(); l

18、ong begin, end; CLOCK(begin); printf(%ld:t Producer %dt produced %dn, (long)(begin-threadStart), id, rnd); sem_wait(&empty); pthread_mutex_lock(&mutex); (CLOCK(end), insert_item(rnd) ? printf(%ld:t Producer %dt have put %dt after %dt millisecondsn,end-threadStart, id, rnd, end-begin) : printf(%ld:t

19、Producer %dt Report Error!n, end-threadStart, id); pthread_mutex_unlock(&mutex); sem_post(&full); */消費(fèi)者:/* Consumer* Try to consume items from the buffer* If the buffer is empty, waiting* When try to consume, we output like that: Consumer 3 want to consume* When successfully consumed, we output: Con

20、sumer 3 consumed 222 after 100 milliseconds* The milliseconds is the timespan from the consumer try to consume the item* When the buffer is empty but the consumer consumed the item, an error occurred* (No way it will happen.)*/#define CTIMESPANMAX 5000void * consumer(void* params) int id=*(int *)par

21、ams; while(true) SLEEP(rand()%CTIMESPANMAX); long begin, end; CLOCK(begin); printf(%ld:t Consumer %dt want to consumen, begin-threadStart, id); sem_wait(&full); pthread_mutex_lock(&mutex); buffer_item item=buffercurrentIndex; (CLOCK(end), remove_item(&item) ? printf(%ld:t Consumer %dt consumed %dt a

22、fter %dt millisecondsn, end-threadStart, id, item, end-begin) : printf(%ld:t Consumer %dt Report Error!n, end-threadStart, id); pthread_mutex_unlock(&mutex); sem_post(&empty); */主函數(shù):int main(int argc, char* argv) srand(unsigned int(time(0); / Init mutex, full and empty pthread_mutex_init(&mutex, NUL

23、L); sem_init(&full, 0, BUFFER_SIZE); sem_init(&empty, 0, BUFFER_SIZE); int i=0; / e. No item in the buffer now, so full is full for(i=0; iBUFFER_SIZE; i+) sem_wait(&full); int sleepTime=0; int producerCount=0; int consumerCount=0; printf(How long to sleep before terminating: ); scanf_s(%d, &sleepTime); printf(The number of producer threads: ); scanf_s(%d, &producerCount); printf(The number of consumer threads: ); scanf_s(%d, &consume

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論