版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、實驗二:讀者寫者問題班級: 學號: 姓名: 實驗二:讀者寫者問題一、實驗目的1. 通過編寫和調(diào)試程序以加深對進程、線程管理方案的理解;2. 熟悉Windows多線程程序設(shè)計方法;二、實驗要求在Windows環(huán)境下,創(chuàng)建一個控制臺進程,此進程包含n個線程。用這n個線程來表示n個讀者或?qū)懻?。每個線程按相應測試數(shù)據(jù)文件(后面介紹)的要求進行讀寫操作。用信號量機制分別實現(xiàn)讀者優(yōu)先和寫者優(yōu)先問題。讀者-寫者問題的讀寫操作限制(包括讀者優(yōu)先和寫者優(yōu)先)1) 寫-寫互斥:不能有兩個寫者同時進行寫操作2) 讀-寫互斥:不能同時有一個線程在讀,而另一個線程在寫。3) 讀-讀允許:可以有一個或多個讀者在讀。讀者優(yōu)
2、先的附加限制:如果讀者申請進行讀操作時已有另一個讀者正在進行讀操作,則該讀者可直接開始讀操作。運行結(jié)果顯示要求:要求在每個線程創(chuàng)建、發(fā)出讀寫申請、開始讀寫操作和結(jié)束讀寫操作時分別顯示一行提示信息,以確定所有處理都遵守相應的讀寫操作限制。測試數(shù)據(jù)文件包括 n行測試數(shù)據(jù),分別描述創(chuàng)建的n個線程是讀者還是寫者,以及讀寫操作的開始時間和持續(xù)時間。每行測試數(shù)據(jù)包括四個字段,每個字段間用空格分隔。第1個字段為正整數(shù),表示線程的序號。第2個字段表示線程的角色,R表示讀者,W表示寫者。第3個字段為一個正數(shù),表示讀寫開始時間:線程創(chuàng)建后,延遲相應時間(單位為秒)后發(fā)出對共享資源的讀寫申請。第4個字段為
3、一個正數(shù),表示讀寫操作的延遲時間。當線程讀寫申請成功后,開始對共享資源進行讀寫操作,該操作持續(xù)相應時間后結(jié)束,釋放該資源。下面是一個測試數(shù)據(jù)文件的例子(在記事本手工錄入數(shù)據(jù)):1 R 3 52 W 4 53 R 5 24 R 6 55 W 5.1 3三、實驗環(huán)境硬件設(shè)備:個人計算機。系統(tǒng)軟件:windows操作系統(tǒng),Visual C+6.0編譯環(huán)境。四、實驗原理所謂讀者寫者問題,可以這樣的描述,有一群寫者和一群讀者,寫者在寫同一本書,讀者也在讀這本書,多個讀者可以同時讀這本書,但是,只能有一個寫者在寫書,并且,讀者比寫者優(yōu)先,也就是說,讀者和寫者同時提出請求時,讀者優(yōu)先。當讀者提出請求時需要有
4、一個互斥操作,另外,需要有一個信號量S來當前是否可操作。信號量機制是支持多道程序的并發(fā)操作系統(tǒng)設(shè)計中解決資源共享時進程間的同步與互斥的重要機制,而讀者寫者則是這一機制的一個經(jīng)典范例。與記錄型信號量解決讀者寫者問題不同,信號量機制它增加了一個限制,即最多允許RN個讀者同時讀。為此,又引入了一個信號量L,并賦予初值為RN,通過執(zhí)行wait(L,1,1)操作,來控制讀者的數(shù)目,每當有一個讀者進入時,就要執(zhí)行wait(L,1,1)操作,使L的值減1。當有RN個讀者進入讀后,L便減為0,第RN+1 個讀者要進入讀時,必然會因wait(L,1,1)操作失敗而堵塞。對利用信號量來解決讀者寫者問題的描述如下:
5、Var RN integer;L,mx:semaphore: =RN,1;BeginParbeginReader :beginRepeatSwait(L,1,1);Swait(mx,1,0);Perform reader operation;Ssignal(L,1);Until false;EndWriter :beginRepeatSwait(mx ,1,1,l,RN,0);Perform writer operation;Ssignal(mx,1);Until false;EndParendEnd其中,Swait(mx,1,0)語句起著開關(guān)作用,只要無Writer進程進入些,mx=1,re
6、ader進程就都可以進入讀。但是要一旦有Writer進程進入寫時,其MX=0,則任何reader進程就都無法進入讀。Swait(mx ,1,1,l,RN,0)語句表示僅當既無Write進程在寫(mx=1),又無reader進程在讀(L=RN)時,writer進程才能進入臨界區(qū)寫。將所有的讀者和所有的寫者分別放進兩個等待隊列中,當讀允許時就讓讀者隊列釋放一個或多個讀者,當寫允許時,釋放第一個寫者操作。讀者寫者問題的定義如下:有一個許多進程共享的數(shù)據(jù)區(qū),這個數(shù)據(jù)區(qū)可以是一個文件或者主存的一塊空間;有一些只讀取這個數(shù)據(jù)區(qū)的進程(Reader)和一些只往數(shù)據(jù)區(qū)寫數(shù)據(jù)的進程(Writer),此外還需要滿
7、足以下條件:1)任意多個讀進程可以同時讀這個文件;2) 一次只有一個寫進程可以往文件中寫;3)如果一個寫進程正在進行操作,禁止任何讀進程度文件。程序由三部分組成:1.讀者模塊:包括系統(tǒng)調(diào)用接口,讀者活動描述主程序。系統(tǒng)接口主要功能是通過管道向父進程發(fā)送系統(tǒng)調(diào)用命令,并讀取父進程送來的返回值。2.寫者模塊:包括系統(tǒng)調(diào)用接口,寫者活動描述主程序。讀者-寫者活動程序根據(jù)臨界資源的共享,互斥原則編制。3.主控模塊:主控模塊實現(xiàn)系統(tǒng)初始化系統(tǒng)調(diào)用命令接收與解釋執(zhí)行,系統(tǒng)調(diào)用功能的實現(xiàn)(包括信號量機制),及讀者-寫者活動過程記錄與顯示。五、實驗結(jié)果使用的測試文件如下:1 R 3 52 W 4 53 R 5
8、 24 R 6 55 W 5.1 3讀者優(yōu)先:按時間順序,進程1發(fā)送讀請求,并進入讀文件。2發(fā)送寫請求,讀寫互斥,不能進行寫操作。3發(fā)送讀請求,并開始讀。5發(fā)送寫請求,同進程2。4發(fā)送讀請求,并開始讀。按時間順序,進程1,3,4先后完成讀操作,2開始寫操作,寫操作不能同時進行,2完成寫操作后,5才能開始寫操作。寫著優(yōu)先:按時間順序,進程1發(fā)送讀請求,并進入讀文件。2發(fā)送寫請求,讀寫互斥,不能進行寫操作,3發(fā)送讀請求,5發(fā)送寫請求,4發(fā)送讀請求。1完成讀請求后,由于寫者優(yōu)先,2進行寫操作,并且其他操作不能進行。2完成寫操作后,5進行寫操作。完成后按順序先后同時進行3,4讀操作。六、感想體會七、實
9、驗代碼# include "windows.h"# include <conio.h> # include <stdlib.h> # include <fstream.h> # include <io.h> # include <string.h> # include <stdio.h> # define READER 'R'/ 讀者 # define WRITER 'W'/ 寫者 # define INTE_PER_SEC 1000/ 每秒時鐘中斷數(shù)目# define
10、MAX_THREAD_NUM 64/ 最大線程數(shù)目# define MAX_FILE_NUM 32/ 最大數(shù)據(jù)文件數(shù)目# define MAX_STR_LEN 32/ 字符串長度int readcount = 0;/ 讀者數(shù)目 int writecount = 0;/ 寫者數(shù)目CRITICAL_SECTION RP_Write;/ 臨界區(qū) CRITICAL_SECTION cs_Write; CRITICAL_SECTION cs_Read; struct ThreadInfo intserial;/ 線程序號charentity;/ 線程類別 (判斷是讀者線程還是寫者線程)doubledel
11、ay;/ 線程延遲doublepersist;/ 線程讀寫操作持續(xù)時間 ;/ 讀者優(yōu)先-讀者線程/ p: 讀者線程信息void RP_ReaderThread(void* p) / 互斥變量HANDLE h_Mutex;h_Mutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "mutex_for_readcount" ) ;DWORD wait_for_mutex;/ 等待互斥變量所有權(quán)DWORD m_delay;/ 延遲時間DWORD m_persist;/ 讀文件持續(xù)時間int m_serial;/ 線程序號/ 從參數(shù)中獲得信息m_se
12、rial = ( (ThreadInfo*) (p) ) -> serial;m_delay = (DWORD) ( ( (ThreadInfo*) (p) ) -> delay*INTE_PER_SEC) ;m_persist = (DWORD) ( ( (ThreadInfo*) (p) ) -> persist*INTE_PER_SEC) ;Sleep(m_delay) ;/ 延遲等待printf( "Reader thread %d sents the reading require.n" , m_serial) ; / 等待互斥信號,保證對rea
13、dcount的訪問、修改互斥wait_for_mutex = WaitForSingleObject (h_Mutex, -1) ;/ 讀者數(shù)目增加readcount +;if (readcount = 1) / 第一個讀者,等待資源EnterCriticalSection(&RP_Write) ; ReleaseMutex(h_Mutex) ;/ 釋放互斥信號/ 讀文件printf( "Reader thread %d begins to read file.n" , m_serial) ;Sleep(m_persist) ;/ 退出線程printf("
14、Reader thread %d finished reading file.n" , m_serial) ;/ 等待互斥信號,保證對readcount的訪問、修改互斥wait_for_mutex = WaitForSingleObject(h_Mutex, -1) ;/ 讀者數(shù)目減少readcount -;if (readcount = 0) / 如果所有讀者讀完,喚醒寫者LeaveCriticalSection(&RP_Write) ; ReleaseMutex(h_Mutex) ;/ 釋放互斥信號 / 讀者優(yōu)先-寫者線程/ p: 寫者線程信息void RP_Writer
15、Thread(void* p) DWORD m_delay;/ 延遲時間DWORD m_persist;/ 寫文件持續(xù)時間int m_serial;/ 線程序號/ 從參數(shù)中獲得信息m_serial = ( (ThreadInfo*) (p) ) -> serial;m_delay = (DWORD) ( ( (ThreadInfo* ) (p) ) -> delay * INTE_PER_SEC) ;m_persist = (DWORD) ( ( (ThreadInfo* ) (p) ) -> persist * INTE_PER_SEC) ;Sleep(m_delay) ;
16、/ 延遲等待printf("Writer thread %d sents the writing require.n" , m_serial) ;/ 等待資源EnterCriticalSection(&RP_Write);/ 寫文件printf( "Writer thread %d begins to write to the file.n" , m_serial) ;Sleep(m_persist) ;/ 退出線程printf("Writer thread %d finishing writing to the file.n"
17、; , m_serial) ;/ 釋放資源LeaveCriticalSection(&RP_Write) ;/ 讀者優(yōu)先處理函數(shù)/ file: 文件名void ReaderPriority(char * file) DWORD n_thread = 0;/ 線程數(shù)目DWORD thread_ID;/ 線程IDDWORD wait_for_all;/ 等待所有線程結(jié)束/ 互斥對象HANDLE h_Mutex;h_Mutex = CreateMutex(NULL, FALSE, "mutex_for_readcount" ) ;/ 線程對象的數(shù)組HANDLE h_Thr
18、ead MAX_THREAD_NUM ;ThreadInfo thread_infoMAX_THREAD_NUM ;readcount = 0;/ 初始化readcountInitializeCriticalSection(&RP_Write) ;/ 初始化臨界區(qū)ifstream inFile;inFile.open(file) ;/ 打開文件printf("Reader Priority: n n" ) ;while (inFile)/ 讀入每一個讀者、寫者的信息inFile >> thread_infon_thread.serial;inFile &
19、gt;> thread_infon_thread.entity;inFile >> thread_infon_thread.delay;inFile >> thread_infon_thread + .persist;inFile.get() ; for (int i = 0; i < (int) (n_thread) ; i +) if (thread_infoi.entity = READER | thread_infoi.entity = 'r' )/ 創(chuàng)建讀者線程h_Threadi = CreateThread(NULL, 0, (L
20、PTHREAD_START_ROUTINE) (RP_ReaderThread) ,&thread_infoi , 0, &thread_ID) ;else / 創(chuàng)建寫者線程h_Threadi = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE) (RP_WriterThread) ,&thread_infoi , 0, &thread_ID) ; / 等待所有線程結(jié)束wait_for_all = WaitForMultipleObjects(n_thread, h_Thread, TRUE, -1) ;printf(&
21、quot;All reader and writer have finished operating.n" ) ; / 寫者優(yōu)先-讀者線程/ p: 讀者線程信息 void WP_ReaderThread(void * p) / 互斥變量HANDLE h_Mutex1;h_Mutex1 = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "mutex1" ) ;HANDLE h_Mutex2;h_Mutex2 = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "mutex2" ) ;DWORD wai
22、t_for_mutex1;/ 等待互斥變量所有權(quán)DWORD wait_for_mutex2;DWORD m_delay;/ 延遲時間DWORD m_persist;/ 讀文件持續(xù)時間int m_serial;/ 線程序號/ 從參數(shù)中獲得信息m_serial = ( (ThreadInfo* ) (p) ) -> serial;m_delay = (DWORD) ( ( (ThreadInfo* ) (p) ) -> delay * INTE_PER_SEC) ;m_persist = (DWORD) ( ( (ThreadInfo* ) (p) ) -> persist *
23、INTE_PER_SEC) ;Sleep(m_delay) ;/ 延遲等待printf("Reader thread %d sents the reading require.n" , m_serial) ;wait_for_mutex1 = WaitForSingleObject(h_Mutex1, -1) ;/ 進入讀者臨界區(qū)EnterCriticalSection(&cs_Read) ;/ 阻塞互斥對象mutex2,保證對readcount的訪問、修改互斥wait_for_mutex2 = WaitForSingleObject(h_Mutex2, -1) ;
24、 / 修改讀者數(shù)目readcount +;if (readcount = 1) / 如果是第一個讀者,等待寫者寫完EnterCriticalSection(&cs_Write) ; ReleaseMutex(h_Mutex2) ;/ 釋放互斥信號mutex2/ 讓其他讀者進入臨界區(qū)LeaveCriticalSection(&cs_Read) ;ReleaseMutex(h_Mutex1) ;/ 讀文件printf("Reader thread %d begins to read file.n" , m_serial) ;Sleep(m_persist) ;/
25、 退出線程printf("Reader thread %d finished reading file.n" , m_serial) ;/ 阻塞互斥對象mutex2,保證對readcount的訪問、修改互斥wait_for_mutex2 = WaitForSingleObject(h_Mutex2, -1) ;readcount - ;if (readcount = 0)/ 最后一個讀者,喚醒寫者LeaveCriticalSection(&cs_Write) ; ReleaseMutex(h_Mutex2) ;/ 釋放互斥信號/ 寫者優(yōu)先-寫者線程/ p: 寫者線程
26、信息void WP_WriterThread(void * p) DWORD m_delay;/ 延遲時間DWORD m_persist;/ 寫文件持續(xù)時間int m_serial;/ 線程序號DWORD wait_for_mutex3;/ 互斥對象HANDLE h_Mutex3;h_Mutex3 = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "mutex3" ) ; / 從參數(shù)中獲得信息m_serial = ( (ThreadInfo* ) (p) ) -> serial;m_delay = (DWORD) ( ( (ThreadInfo
27、* ) (p) ) -> delay * INTE_PER_SEC) ;m_persist = (DWORD) ( ( (ThreadInfo* ) (p) ) -> persist * INTE_PER_SEC) ;Sleep(m_delay) ;/ 延遲等待printf("Writer thread %d sents the writing require.n" , m_serial) ;/ 阻塞互斥對象mutex3, 保證對writecount的訪問、修改互斥wait_for_mutex3 = WaitForSingleObject(h_Mutex3, -
28、1) ;writecount + ;/ 修改寫者數(shù)目if (writecount = 1)/ 第一個寫者,等待讀者讀完EnterCriticalSection(&cs_Read) ; ReleaseMutex(h_Mutex3) ;/ 進入寫者臨界區(qū)EnterCriticalSection(&cs_Write) ;/ 寫文件printf("Writer thread %d begins to write to the file.n" , m_serial) ;Sleep(m_persist) ;/ 退出線程printf("Writer thread
29、 %d finishing writing to the file.n" , m_serial) ;/ 離開臨界區(qū)LeaveCriticalSection(&cs_Write) ;/ 阻塞互斥對象mutex3,保證對writecount的訪問、修改互斥wait_for_mutex3 = WaitForSingleObject(h_Mutex3, -1) ;writecount -;if (writecount = 0)/ 寫者寫完,讀者可以讀LeaveCriticalSection(&cs_Read) ;ReleaseMutex(h_Mutex3) ; / / / /
30、 / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / 寫者優(yōu)先處理函數(shù)/ file: 文件名void WriterPriority(char * file)DWORD n_thread = 0;/ 線程數(shù)目DWORD thread_ID;/ 線程IDDWORD wait_for_all;/ 等待所有線程結(jié)束/ 互斥對象HANDLE h_Mutex1;h_Mutex1 = Cre
31、ateMutex(NULL, FALSE, "mutex1" ) ;HANDLE h_Mutex2;h_Mutex2 = CreateMutex(NULL, FALSE, "mutex2" ) ;HANDLE h_Mutex3;h_Mutex3 = CreateMutex(NULL, FALSE, "mutex3" ) ;/ 線程對象HANDLE h_ThreadMAX_THREAD_NUM ;ThreadInfo thread_infoMAX_THREAD_NUM ;readcount = 0;/ 初始化readcountwrite
32、count = 0; / 初始化writecountInitializeCriticalSection(&cs_Write) ;/ 初始化臨界區(qū)InitializeCriticalSection(&cs_Read) ;ifstream inFile;inFile.open(file) ;/ 打開文件printf("Writer Priority: n n" ) ;while (inFile)/ 讀入每一個讀者、寫者的信息inFile >> thread_infon_thread.serial;inFile >> thread_info
33、n_thread.entity;inFile >> thread_infon_thread.delay;inFile >> thread_infon_thread +.persist;inFile.get() ;for (int i = 0; i < (int) (n_thread) ; i +)if (thread_infoi.entity = READER | thread_infoi.entity = 'r' )/ 創(chuàng)建讀者線程h_Threadi = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (WP_ReaderThread) ,&thread_infoi , 0, &thread_ID) ;else / 創(chuàng)建寫者線程h_Threadi = CreateThr
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024污水處理廠運營合同書(范本)
- 2024幼兒園租房合同協(xié)議書樣本
- 房產(chǎn)抵押擔保借款合同書范例
- 2024貨船租賃合同范本范文
- 股權(quán)抵押借款合同范文2024年
- 店面租房門面房租房合同協(xié)議
- 商業(yè)鋪租賃合同格式
- 項目合作協(xié)議書模板示例
- 2024居間合同,居間合同范例
- 技術(shù)合作協(xié)議樣式
- 精品堆垛機安裝指導書
- 前臺月度績效考核表(KPI)
- 雞的飼養(yǎng)管理-優(yōu)質(zhì)課件
- 德育課(共19張PPT)
- 歷史幽憤的現(xiàn)代回響——《記念劉和珍君》課堂實錄
- 化學微生物學第7章 微生物轉(zhuǎn)化
- 《少年正是讀書時》-完整版PPT課件
- 四、貼標機基本調(diào)整法1
- 船舶建造方案
- 35KV集電線路鐵塔組立專項方案
- 不銹鋼管規(guī)格表大全以及理論重量表大全
評論
0/150
提交評論