河北科技大學操作系統課程設計——讀者寫者問題
# include <windows.h>
# include <conio.h>
# include <stdlib.h>
# include <fstream>
# include <io.h>
# include <string.h>
# include <stdio.h>
using namespace std;
# define READER 'R'
# define WRITER 'W'
# define MAX_THREAD_NUM 32
CRITICAL_SECTION RP_Write;
CRITICAL_SECTION pright;
CRITICAL_SECTION w_Mutex;
CRITICAL_SECTION cs;
# define INTE_PER_SEC 100 int flag;
int readcount= 0 ;
int writecount= 0 ;
struct ThreadInfo
{ int serial; char entity; double delay; double persist;
} ;
ThreadInfo thread_info[ MAX_THREAD_NUM] ;
void ReaderPriority ( int num) ;
void RP_ReaderThread ( void * p) ;
void RP_WriterThread ( void * p) ;
void WriterPriority ( int num) ;
void WP_ReaderThread ( void * p) ;
void WP_WriterThread ( void * p) ;
void showInput ( void ) ;
void showWhich ( void ) ;
int main ( )
{ InitializeCriticalSection ( & cs) ; int num; int choice; while ( 1 ) { system ( "cls" ) ; showInput ( ) ; scanf ( "%d" , & choice) ; switch ( choice) { case 1 : system ( "cls" ) ; showWhich ( ) ; break ; case 2 : exit ( 1 ) ; break ; default : printf ( "輸入有誤,請重新輸入!\n" ) ; Sleep ( 1000 ) ; break ; } } system ( "pause" ) ; return 0 ;
}
void showInput ( void )
{ printf ( " *********請選擇功能*********\n" ) ; printf ( " * *\n" ) ; printf ( " * 1:模擬讀者寫者問題 *\n" ) ; printf ( " * *\n" ) ; printf ( " * 2:退出系統 *\n" ) ; printf ( " * *\n" ) ; printf ( " ****************************\n" ) ;
}
void show ( )
{ printf ( " *********請選擇功能*********\n" ) ; printf ( " * *\n" ) ; printf ( " * 1:讀者優先 *\n" ) ; printf ( " * 2:寫者優先 *\n" ) ; printf ( " * 3:返回上一級 *\n" ) ; printf ( " * 4:清屏并繼續 *\n" ) ; printf ( " * 5:退出系統 *\n" ) ; printf ( " * *\n" ) ; printf ( " ****************************\n" ) ;
}
void showWhich ( void )
{ int num; int choice; printf ( "請輸入總的讀者寫者線程數:(<=32)\n" ) ; scanf ( "%d" , & num) ; for ( int i= 0 ; i< num; i++ ) { printf ( "請輸入*線程號*線程類別(R/W)*線程開始時間*線程持續時間:\n" ) ; scanf ( "%d %c %lf %lf" , & thread_info[ i] . serial, & thread_info[ i] . entity, & thread_info[ i] . delay, & thread_info[ i] . persist) ; } system ( "cls" ) ; show ( ) ; while ( 1 ) { scanf ( "%d" , & choice) ; switch ( choice) { case 1 : printf ( "序號 讀者或寫者 開始時間 持續時間\n" ) ; for ( int i= 0 ; i< num; i++ ) { printf ( " %d %c %f %f \n" , thread_info[ i] . serial, thread_info[ i] . entity, thread_info[ i] . delay, thread_info[ i] . persist) ; } ReaderPriority ( num) ; continue ; case 2 : printf ( "序號 讀者或寫者 開始時間 持續時間\n" ) ; for ( int i= 0 ; i< num; i++ ) { printf ( " %d %c %f %f \n" , thread_info[ i] . serial, thread_info[ i] . entity, thread_info[ i] . delay, thread_info[ i] . persist) ; } WriterPriority ( num) ; continue ; case 3 : flag= 1 ; break ; case 4 : system ( "cls" ) ; show ( ) ; continue ; case 5 : flag= 0 ; break ; default : printf ( "輸入有誤,請重新輸入!\n" ) ; Sleep ( 1000 ) ; system ( "cls" ) ; show ( ) ; continue ; } ; if ( flag== 1 ) break ; if ( flag== 0 ) exit ( 1 ) ; }
}
void ReaderPriority ( int num)
{ DWORD n_thread= num; DWORD thread_ID; DWORD wait_for_all; HANDLE rmutex; rmutex= CreateMutex ( NULL , FALSE, "mutex_for_readcount" ) ; HANDLE h_Thread[ MAX_THREAD_NUM] ; readcount= 0 ; InitializeCriticalSection ( & RP_Write) ; printf ( "讀者優先:(縱坐標為執行順序)\n" ) ; for ( int i= 0 ; i< ( int ) ( n_thread) ; i++ ) { if ( thread_info[ i] . entity== READER || thread_info[ i] . entity== 'r' ) h_Thread[ i] = CreateThread ( NULL , 0 , ( LPTHREAD_START_ROUTINE) ( RP_ReaderThread) , & thread_info[ i] , 0 , & thread_ID) ; else h_Thread[ i] = CreateThread ( NULL , 0 , ( LPTHREAD_START_ROUTINE) ( RP_WriterThread) , & thread_info[ i] , 0 , & thread_ID) ; } wait_for_all= WaitForMultipleObjects ( n_thread, h_Thread, TRUE, - 1 ) ; printf ( "所有操作完成\n\n" ) ;
}
void RP_ReaderThread ( void * p)
{ int m_ID; DWORD m_delay; DWORD m_persist; m_ID= ( ( ThreadInfo * ) ( p) ) -> serial; m_delay= ( DWORD) ( ( ( ThreadInfo * ) ( p) ) -> delay* INTE_PER_SEC) ; m_persist= ( DWORD) ( ( ( ThreadInfo * ) ( p) ) -> persist* INTE_PER_SEC) ; HANDLE rmutex; rmutex= OpenMutex ( MUTEX_ALL_ACCESS, FALSE, "mutex_for_readcount" ) ; DWORD wait_for_mutex; Sleep ( m_delay) ; EnterCriticalSection ( & cs) ; for ( int i= 1 ; i< m_ID; i++ ) printf ( " " ) ; printf ( "讀者%d讀請求\n" , m_ID) ; LeaveCriticalSection ( & cs) ; wait_for_mutex= WaitForSingleObject ( rmutex, - 1 ) ; readcount++ ; if ( readcount== 1 ) EnterCriticalSection ( & RP_Write) ; ReleaseMutex ( rmutex) ; EnterCriticalSection ( & cs) ; for ( int j= 1 ; j< m_ID; j++ ) printf ( " " ) ; printf ( "讀者%d開始讀\n" , m_ID) ; LeaveCriticalSection ( & cs) ; Sleep ( m_persist) ; EnterCriticalSection ( & cs) ; for ( int k= 1 ; k< m_ID; k++ ) printf ( " " ) ; printf ( "讀者%d完成讀\n" , m_ID) ; LeaveCriticalSection ( & cs) ; wait_for_mutex= WaitForSingleObject ( rmutex, - 1 ) ; readcount-- ; if ( readcount== 0 ) LeaveCriticalSection ( & RP_Write) ; ReleaseMutex ( rmutex) ;
}
void RP_WriterThread ( void * p)
{ DWORD m_delay; DWORD m_persist; int m_ID; m_ID= ( ( ThreadInfo * ) ( p) ) -> serial; m_delay= ( DWORD) ( ( ( ThreadInfo * ) ( p) ) -> delay* INTE_PER_SEC) ; m_persist= ( DWORD) ( ( ( ThreadInfo * ) ( p) ) -> persist* INTE_PER_SEC) ; Sleep ( m_delay) ; EnterCriticalSection ( & cs) ; for ( int i= 1 ; i< m_ID; i++ ) printf ( " " ) ; printf ( "寫者%d寫請求\n" , m_ID) ; LeaveCriticalSection ( & cs) ; EnterCriticalSection ( & RP_Write) ; EnterCriticalSection ( & cs) ; for ( int l= 1 ; l< m_ID; l++ ) printf ( " " ) ; printf ( "寫者%d開始寫\n" , m_ID) ; LeaveCriticalSection ( & cs) ; Sleep ( m_persist) ; EnterCriticalSection ( & cs) ; for ( int q= 1 ; q< m_ID; q++ ) printf ( " " ) ; printf ( "寫者%d完成寫\n" , m_ID) ; LeaveCriticalSection ( & cs) ; LeaveCriticalSection ( & RP_Write) ;
}
void WriterPriority ( int num) { DWORD n_thread= num; DWORD thread_ID; DWORD wait_for_all; HANDLE r_Mutex; HANDLE writerm; r_Mutex= CreateMutex ( NULL , FALSE, "r_Mutex" ) ; writerm= CreateMutex ( NULL , FALSE, "writerm" ) ; InitializeCriticalSection ( & pright) ; InitializeCriticalSection ( & w_Mutex) ; HANDLE h_Thread[ MAX_THREAD_NUM] ; readcount= 0 ; writecount= 0 ; printf ( "寫者優先:(縱坐標為執行順序)\n" ) ; for ( int i= 0 ; i< ( int ) ( n_thread) ; i++ ) { if ( thread_info[ i] . entity== READER || thread_info[ i] . entity== 'r' ) h_Thread[ i] = CreateThread ( NULL , 0 , ( LPTHREAD_START_ROUTINE) ( WP_ReaderThread) , & thread_info[ i] , 0 , & thread_ID) ; else h_Thread[ i] = CreateThread ( NULL , 0 , ( LPTHREAD_START_ROUTINE) ( WP_WriterThread) , & thread_info[ i] , 0 , & thread_ID) ; } wait_for_all= WaitForMultipleObjects ( n_thread, h_Thread, TRUE, - 1 ) ; printf ( "所有操作完成\n" ) ;
}
void WP_ReaderThread ( void * p) { DWORD m_delay; DWORD m_persist; int m_ID; m_ID= ( ( ThreadInfo * ) ( p) ) -> serial; m_delay= ( DWORD) ( ( ( ThreadInfo * ) ( p) ) -> delay* INTE_PER_SEC) ; m_persist= ( DWORD) ( ( ( ThreadInfo * ) ( p) ) -> persist* INTE_PER_SEC) ; HANDLE r_Mutex; r_Mutex= OpenMutex ( MUTEX_ALL_ACCESS, FALSE, "r_Mutex" ) ; DWORD wait_for_rmutex; Sleep ( m_delay) ; EnterCriticalSection ( & cs) ; for ( int i= 1 ; i< m_ID; i++ ) printf ( " " ) ; printf ( "讀者%d讀請求\n" , m_ID) ; LeaveCriticalSection ( & cs) ; EnterCriticalSection ( & pright) ; wait_for_rmutex= WaitForSingleObject ( r_Mutex, INFINITE) ; if ( readcount== 0 ) EnterCriticalSection ( & w_Mutex) ; readcount++ ; ReleaseMutex ( r_Mutex) ; LeaveCriticalSection ( & pright) ; EnterCriticalSection ( & cs) ; for ( int s= 1 ; s< m_ID; s++ ) printf ( " " ) ; printf ( "讀者%d開始讀\n" , m_ID) ; LeaveCriticalSection ( & cs) ; Sleep ( m_persist) ; EnterCriticalSection ( & cs) ; for ( int r= 1 ; r< m_ID; r++ ) printf ( " " ) ; printf ( "讀者%d完成讀\n" , m_ID) ; LeaveCriticalSection ( & cs) ; wait_for_rmutex= WaitForSingleObject ( r_Mutex, INFINITE) ; readcount-- ; if ( readcount== 0 ) LeaveCriticalSection ( & w_Mutex) ; ReleaseMutex ( r_Mutex) ;
}
void WP_WriterThread ( void * p) { DWORD m_delay; DWORD m_persist; int m_ID; m_ID= ( ( ThreadInfo * ) ( p) ) -> serial; m_delay= ( DWORD) ( ( ( ThreadInfo * ) ( p) ) -> delay* INTE_PER_SEC) ; m_persist= ( DWORD) ( ( ( ThreadInfo * ) ( p) ) -> persist* INTE_PER_SEC) ; HANDLE writerm; writerm= OpenMutex ( MUTEX_ALL_ACCESS, FALSE, "writerm" ) ; DWORD wait_for_writerm; Sleep ( m_delay) ; EnterCriticalSection ( & cs) ; for ( int i= 1 ; i< m_ID; i++ ) printf ( " " ) ; printf ( "寫者%d寫請求\n" , m_ID) ; LeaveCriticalSection ( & cs) ; wait_for_writerm= WaitForSingleObject ( writerm, INFINITE) ; writecount++ ; if ( writecount== 1 ) EnterCriticalSection ( & pright) ; ReleaseMutex ( writerm) ; EnterCriticalSection ( & w_Mutex) ; EnterCriticalSection ( & cs) ; for ( int h= 1 ; h< m_ID; h++ ) printf ( " " ) ; printf ( "寫者%d開始寫\n" , m_ID) ; LeaveCriticalSection ( & cs) ; Sleep ( m_persist) ; EnterCriticalSection ( & cs) ; for ( int t= 1 ; t< m_ID; t++ ) printf ( " " ) ; printf ( "寫者%d完成寫\n" , m_ID) ; LeaveCriticalSection ( & cs) ; LeaveCriticalSection ( & w_Mutex) ; wait_for_writerm= WaitForSingleObject ( writerm, INFINITE) ; writecount-- ; if ( writecount== 0 ) LeaveCriticalSection ( & pright) ; ReleaseMutex ( writerm) ;
}