Operating system kernel test reader - writer implementation
Part 1: Description
Reader - a model of classic thread synchronization problem, so I made this article, I hope to help to learn the operating system! I hope to make friends with the majority of programming enthusiasts! As for the reader - writer, I have not described in this way. Since you see this document, I think you should understand the reader's writer problem, so I will start from the code, and there is a brief description. If you don't understand anything, you can contact me in the following ways:
■■■, e-mail: ■■ qq: ■■■■■■■■■■■■■
My homepage: http://www.■ R ..com
Special note: The implementation technology of this questioning document is:
"Windows Core Experiment Tutorial" Machinery Industry Press ISBN: 7-111-10880-9 / TP.2600
The copyright is also owned by the original book! I hope to see this document can guarantee the copyright of the original book! I just finished the part of them!
Special Note:
If you test your theoretical level and design of the operating system, you want you to see this document first! I have tried the design independently!
Part II: Implementation
Operating system experiment reader - writer Implementation Code Description Document
/
Reader - writer's read and write restrictions (including readers priority and writer)
1) Write - write mutual exclusion, that is, two writers can be written simultaneously
2) Read - write mutual exclusion, that is, there is a reader at the same time, but there is a writer in writing.
3) Read the permission, you can read more than 2 readers
Reader's preferred limitations:
If a reader applies for a read operation, there is already a reader in reading, then the reader can read directly.
Write priority limit:
If a reader applies for a read operation, the writer is waiting for the reader to wait until the writer is waiting.
/
Test data format
In the file thread.dat,
1 r 3 5
2 W 4 5
....
The first represents the ID of the thread, the second field represents a read operation or writing, the third field represents the start time of the operation, and the fourth field is duration.
/
analysis:
Put all the readers and all the writers in two waiting queues, when reading allows the reader queue to release one or more readers, and release the first writer operation when writing to allow.
The reader is preferred:
If no writer is being operated, the reader does not need to wait, and use a integer variable readCount to record the current reader number, used to determine if the writer thread is released, (when readcout = 0, explaining that all readers have finished reading, Release a writer thread), each reader must modify the readcount before reading, in order to modify the READCOUNT for mutually exclusive, require a mutex MUTEX to achieve mutual exclusion.
In addition, in order to implement write-write mutual exclusion, a critical area object Write is required. When the writer issues a write request, you must first get the ownership of the critical area object. In this way, read / write mutual exclusion can be implemented. When ReadCount = 1, (ie, when the first reader arrives,), the reader thread must also apply for ownership of the critical area object.
When the reader owns the ownership of the critical area, the writer is blocked on the critical area object write. When the writer has a critical area object ownership, the first judgment readcount == 1, the rest of the reader is blocked on Mutex because of the judgment of ReadCount! Write priority:
The writer is priority and readers have the same place, different places: Once there is a writer coming, you should write the writer as soon as possible, if there is a writer waiting, the new to reader can not read the operation, Add a integer variable WriteCount to record the number of writers. When WriteCount = 0, you can release the reader to read operation!
In order to achieve mutual exclusive access to the global variable Writecount, a mutex Mutex3 is set.
In order to achieve the writer, set a critical area object read, and when the writer is written or waiting, the reader must block the critical area object read.
In addition to a global variable ReadCount implementation of mutual exclusion, a mutually exclusive object is required to blocked the block in the READ. The two mutual exclusive objects are MUTEX1 and MUTEX2, respectively.
//
The API: Parameter (MSDN View) // Code is not used, but can be used when designing the program in other parts.
CRETHREAD ();
2.exitthread ();
3.Sleep ();
4.createmutex ();
5.releasemutex ();
6.waitforsingleObject ();
7.WaitFormutiPleObjects ();
8.createSemapore ();
9.ReleaseSemapore ();
10.initializecriticalSection ();
11.entercriticalsection ();
12.LeaveCriticalSection ();
///
Original code file name:
1.ReaderandWriter.cpp // Specific implementation
2.Thread.dat // Assisted files, but must not be less.
Part III: Code
One. The specific content of the readERANDWRITER.CPP file:
// From: Windows kernel experiment tutorial
// Mechanical Industry Press
// ISBN: 7-111-10880-9 / TP.2600
// producers: yuhejun@126.com
// for more information: www.surstar.com
// 2005.11.9
//
beijing
changping
// debug vision
// Description: This is analog implementation of a program, reader and writer's question.
// Development Environment: WinXP VC6 Console Application
#include "windows.h"
#include
#include
#include
#include
#include
#include
#define reader 'r' // reader
#define Writer 'W' // Write
#define INTE_PER_SEC 1000 // Number of interruptions per second clock
#define max_thread_num 64 // Maximum number of threads
#define max_file_num 32 // Number of maximum files
#define max_str_len 32 // String length
INT readcount = 0; // reader number
INT WRITECUNT = 0; // Number of writers
Critical_section rp_write; // Critical resources
Critical_section cs_write;
Critical_section cs_read;
Struct ThreadInfo
{
INT serial; // thread serial number
CHAR Entity; // Thread Category (Judgment is the reader or writer thread)
Double delay; // thread delay time
Double persist; // thread read and write operation time
}
///
// reader priority - reader thread
// p: reader thread information
Void RP_Readerthread (Void * P)
{
// Mutually exclusive variable
Handle H_Mutex;
H_Mutex = OpenMuteX (Mutex_all_Access, False, "Mutex_for_Readcount");
DWORD WAIT_FOR_MUTEX; // Waiting for mutex ownership
DWORD M_DELAY; // Delay Time
DWORD M_PERSIST; // Read file duration
INT m_serial; // thread serial number
// Get information from the parameters
m_serial = ((ThreadInfo *) (P)) -> Serial;
m_delay = (dword) ((ThreadInfo *) (P)) -> delay * inte_per_sec);
M_Persist = (DWORD) -> PERSIST * INTE_PER_SEC);
Sleep (m_delay); // Delay waiting
Printf ("Reader Thread% D SENTS The Reading Require./N", M_Serial);
// Waiting for mutually exclusive signals to ensure access to readcount, modify mutual exclusion
WAIT_FOR_MUTEX = WaitforsingleObject (h_mutex, -1);
// reader increases
Readcount ;
IF (readcount == 1)
{
// First reader, waiting for resources
ENTERCRITICALSECTION (& rp_write);
}
ReleaseMutex (h_mutex); // Release the mutually exclusive signal
// read the file
Printf ("Reader Thread% D Begins to Read file./n" ,m_serial);
Sleep (m_persist);
// Exit the thread
Printf ("Reader Thread% D finished Reading file./n", m_serial);
// Waiting for mutually exclusive signals to ensure access to readcount, modify mutual exclusion
WAIT_FOR_MUTEX = WaitforsingleObject (h_mutex, -1);
// reader number reduction
Readcount -;
IF (readcount == 0)
{
// If all readers have finished reading, wake up
LeavecriticalSection (& rp_write);
ReleaseMutex (h_mutex); // Release the mutually exclusive signal
}
//
// P: writer thread information
Void rp_writerthread (void * p)
{
DWORD M_DELAY; // Delay Time
DWORD M_PERSIST; // Write file duration
INT m_serial; // thread serial number
// Get information from the parameters
m_serial = ((ThreadInfo *) (P)) -> Serial;
m_delay = (dword) ((ThreadInfo *) (P)) -> delay * inte_per_sec);
M_Persist = (DWORD) -> PERSIST * INTE_PER_SEC);
Sleep (m_delay);
Printf ("Write Thread% D SENTS The Writing Require./n", M_Serial);
// Waiting for resources
ENTERCRITICALSECTION (& rp_write);
// write file
Printf ("Writer Thread% D Begins to Write to the file./n" ,m_serial);
Sleep (m_persist);
// Exit the thread
Printf ("Write Thread% D Finished Writing to the file./n" ,m_serial);
/ / Release Resources
LeavecriticalSection; & rp_write;
}
//
// reader priority processing function
// file: file name
Void ReaderPriority (Char * file)
{
DWORD N_THREAD = 0; // Thread Number
DWORD THREAD_ID; // Thread ID
DWORD WAIT_FOR_ALL; // Waiting for all threads to end
// Mutually exclusive object
Handle H_Mutex;
H_Mutex = Createmutex (Null, False, "Mutex_for_Readcount");
// array of thread objects
Handle h_thread [MAX_THREAD_NUM];
ThreadInfo Thread_info [MAX_THREAD_NUM];
Readcount = 0; // Initialization ReadCount
InitializecriticalSection (& rp_write); // Initialization Roundation
IFStream Infile;
Infile.open (file);
Printf ("Reader Priority: / N / N");
While (Infile)
{
/ / Read in every reader, write
Infile >> thread_info [n_thread] .serial;
Infile >> thread_info [n_thread].
Infile >> thread_info [n_thread] .delay;
Infile >> Thread_info [n_thread ]. Persist;
INFILE.GET ();
}
For (int i = 0; i <(int) (n_thread); i )
{
IF (thread_info [i] .entity == reader || thread_info [i] .entity == 'r') {
// Create a reader process
H_Thread [i] = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) (rp_readerthread), & thread_info [i], 0, & three_id);
}
Else
{
// Create a write thread
H_Thread [i] = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) (rp_writerthread), & thread_info [i], 0, & thread_id);
}
}
// Waiting for all threads to end
Wait_for_all = WaitFormultipleObjects (n_thread, h_thread, true, -1);
Printf ("All Reader and Writer Have Finished Operating./N");
}
// Write priority - reader thread
// p: reader thread information
Void WP_Readerthread (Void * P)
{
// Mutually exclusive variable
Handle H_Mutex1;
H_Mutex1 = OpenMuteX (Mutex_all_Access, False, "Mutex1");
Handle H_Mutex2;
H_Mutex2 = OpenMuteX (Mutex_all_Access, False, "Mutex2");
DWORD WAIT_FOR_MUTEX1; // Waiting for mutex ownership
DWORD WAIT_FOR_MUTEX2;
DWORD M_DELAY; // Delay Time
DWORD M_PERSIST; // Read file duration
INT M_SERIAL; / / Thread serial number
// Get information from the parameters
m_serial = ((ThreadInfo *) (P)) -> Serial;
m_delay = (dword) ((ThreadInfo *) (P)) -> delay * inte_per_sec);
M_Persist = (DWORD) -> PERSIST * INTE_PER_SEC);
Sleep (m_delay); // Delay waiting
Printf ("Reader Thread% D SENTS The Reading Require./N", M_Serial);
WAIT_FOR_MUTEX1 = WaitforsingleObject (h_mutex1, -1);
// reader into the critical area
ENTERCRITICALSECTION (& CS_READ);
// block the mutual exclusive object MUTEX2 to ensure access and modification of readcount
WAIT_FOR_MUTEX2 = WaitforsingleObject (h_mutex2, -1);
/ / Modify the number of readers
Readcount ;
IF (readcount == 1)
{
// If it is the first reader, wait for the writer to finish
EntercriticalSection (& CS_WRITE);
}
ReleaseMutex (h_mutex2); // Release the mutual exclusion signal MUTEX2
// Let other readers enter the critical area
LeavecriticalSection (& CS_READ);
ReleaseMuteX (H_Mutex1);
// read the file
Printf ("Reader Thread% D Begins to Read file./n" ,m_serial) ;sleep(M_Persist);
// Exit the thread
Printf ("Reader Thread% D finished Reading file./n", m_serial);
// block the mutual exclusive object Mutex2 to ensure access to readcount, modify mutual exclusion
WAIT_FOR_MUTEX2 = WaitforsingleObject (h_mutex2, -1);
Readcount -;
IF (readcount == 0)
{
// Last reader, wake up
LeavecriticalSection (& CS_WRITE);
}
ReleaseMutex (h_mutex2); // Release the mutually exclusive signal
}
///
// writer priority - writer thread
// P: writer thread information
Void wp_writerthread (void * p)
{
DWORD WAIT_FOR_MUTEX3; // Mutually exclusive variable
DWORD M_DELAY; // Delay Time
DWORD M_PERSIST; // Read file duration
INT m_serial; // thread serial number
Handle H_Mutex3;
H_Mutex3 = OpenMuteX (Mutex_all_Access, False, "Mutex3");
// Get information from the parameters
m_serial = ((ThreadInfo *) (P)) -> Serial;
m_delay = (dword) ((ThreadInfo *) (P)) -> delay * inte_per_sec);
M_Persist = (DWORD) -> PERSIST * INTE_PER_SEC);
Sleep (m_delay); // Delay waiting
Printf ("Writer Thread% D SENTS The Reading Require./n", M_Serial);
WAIT_FOR_MUTEX3 = WaitforsingleObject (h_mutex3, -1);
Writecount ; // Modify the number of writers
IF (writecount == 1)
{
ENTERCRITICALSECTION (& CS_READ);
}
ReleaseMutex (H_Mutex3);
EntercriticalSection (& CS_WRITE);
Printf ("Writer Thread% D Begins to Write to the file./n" ,m_serial);
Sleep (m_persist);
Printf ("Writer Thread% D Finished Writing to the file./n" ,m_serial);
LeavecriticalSection (& CS_WRITE);
WAIT_FOR_MUTEX3 = WaitforsingleObject (h_mutex3, -1);
Writecount -;
IF (writecount == 0)
{
LeavecriticalSection (& CS_READ);
}
ReleaseMutex (H_Mutex3);
}
/
// writer priority processing function
// file: file name
Void WriterPriority (Char * file)
{
DWORD N_THREAD = 0;
DWORD THREAD_ID;
DWORD WAIT_FOR_ALL; HANDLE H_MUTEX1;
H_Mutex1 = CreateMutex (Null, False, "Mutex1");
Handle H_Mutex2;
H_Mutex2 = Createmutex (Null, False, "Mutex2");
Handle H_Mutex3;
H_Mutex3 = Createmutex (Null, False, "Mutex3");
Handle h_thread [MAX_THREAD_NUM];
ThreadInfo Thread_info [MAX_THREAD_NUM];
Readcount = 0;
Writecount = 0;
InitializecriticalSection (& CS_WRITE);
InitializationCriticalSection (& CS_READ);
IFStream Infile;
Infile.open (file);
Printf ("Writer Priority: / N / N");
While (Infile)
{
Infile >> thread_info [n_thread] .serial;
Infile >> thread_info [n_thread].
Infile >> thread_info [n_thread] .delay;
Infile >> Thread_info [n_thread ]. Persist;
INFILE.GET ();
}
For (int i = 0; i <(int) (n_thread); i )
{
IF (thread_info [i] .entity == Reader || THREAD_INFO [i] .entity == 'r')
{
// Create a reader process
H_thread [i] = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) (WP_Readerthread), & Thread_Info [i], 0, & thread_id);
}
Else
{
// Create a write thread
H_thread [i] = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) (WP_WRITERTHREAD), & Thread_info [i], 0, & thread_id);
}
}
// Waiting for all threads to end
Wait_for_all = WaitFormultipleObjects (n_thread, h_thread, true, -1);
Printf ("All Reader and Writer Have Finished Operating./N");
}
/
// master function
Int main (int Argc, char * argv [])
{
CHAR CH;
While (True)
{
PRINTF ("*****************************************************************************************
Printf ("1.Reader priority / n");
Printf ("2.writer priority / n");
Printf ("3.exit to windows / n");
PRINTF ("*****************************************************************************************
Printf ("Enter Your Choice (1, 2, 3):");
Do {
CH = (char) _Getch ();
} while (ch! = '1' && ch! = '2' && ch! = '3'); System ("CLS");
IF (CH == '3')
Return 0;
Else IF (CH == '1')
ReaderPriority ("Thread.dat");
Else
WriterPriority ("thread.dat");
Printf ("/ NPRESS ANY Key to Coutinue:");
_Getch ();
SYSTEM ("CLS");
}
Return 0;
}
two. Thread.dat content
1 R 3 5
2 W 4 5
3 r 5 2
4 r 6 5
5 W 5.1 3
Part IV: Disclaimer
1. I hope everyone will keep the integrity of this document.
2. If you want to use the code, please be famous: copyright belongs to the original book.
3. Please don't think other people will pass this document, I don't take any consequences.
Sunday, November 14, 2004