As with the producer consumer Problem of the second multi-threaded tenth producer Consumer problem , reader writer is also a very famous synchronization problem. The reader writer's question description is very simple, there is a writer many readers, multiple readers can read the file at the same time, but the writer does not allow readers to write the file, the reader is also reading the file when the writer does not go to write files.
Above is the reader's question, similar to the analysis process of producer consumer problems, first to find out what is a "waiting" situation.
First The writer has to wait until there is no reader to write the file.
Second All readers have to wait for the writer to finish writing the file before they can read the file.
After looking for a "wait" situation, then see if there are any resources to mutually exclusive access. Since there is only one writer and the reader is able to share the read file, there is no resource that requires mutually exclusive access according to the topic. Similar to the beautiful color output in the previous article, we color-set the producer output code (see "VC console color Settings" in the console output color settings ). Therefore, there is a mutually exclusive access here, or it is likely that the reader thread will have output before the writer thread restores the console color settings. Therefore, to make a mutually exclusive access to the output statement, the modified reader and the writer's output functions are as follows:
[CPP]View Plaincopy
- Reader thread output function
- void readerprintf (char *pszformat, ...)
- {
- va_list parglist;
- Va_start (Parglist, Pszformat);
- EnterCriticalSection (&g_cs);
- vfprintf (stdout, Pszformat, parglist);
- LeaveCriticalSection (&g_cs);
- Va_end (parglist);
- }
- Writer thread output function
- void writerprintf (char *pszstr)
- {
- EnterCriticalSection (&g_cs);
- Setconsolecolor (Foreground_green);
- printf ("%s\n", pszstr);
- Setconsolecolor (foreground_red | Foreground_green | Foreground_blue);
- LeaveCriticalSection (&g_cs);
- }
The variable parameters used by the reader thread output function are describedin using variable parameters in C,c++ .
resolves the mutex output problem and then considers how to implement the synchronization problem. You can set a variable to record the number of readers who are reading the file, and the first reader to begin reading the file will be responsible for closing the sign that allows the writer to enter, and the last reader to end the reading will be responsible for opening the sign that allows the writer to enter it. So the first kind of "wait" situation is solved. The second "Wait" situation is when a writer enters, so the reader cannot enter, and the task can be accomplished with an event--all readers are waiting for the event and the writer is responsible for triggering the event and setting the event as not triggered. See the code in detail for comments:
[CPP]View Plaincopy
- Reader and writer questions
- #include <stdio.h>
- #include <process.h>
- #include <windows.h>
- Setting the console output color
- BOOL Setconsolecolor (WORD wattributes)
- {
- HANDLE hconsole = GetStdHandle (Std_output_handle);
- if (hconsole = = Invalid_handle_value)
- return FALSE;
- return Setconsoletextattribute (Hconsole, wattributes);
- }
- const INT reader_num = 5; //number of readers
- Critical segments and events
- critical_section G_cs, G_cs_writer_count;
- HANDLE G_heventwriter, G_heventnoreader;
- int g_nreadercount;
- Reader thread output function (Implementation of variable parameter function)
- void readerprintf (char *pszformat, ...)
- {
- va_list parglist;
- Va_start (Parglist, Pszformat);
- EnterCriticalSection (&g_cs);
- vfprintf (stdout, Pszformat, parglist);
- LeaveCriticalSection (&g_cs);
- Va_end (parglist);
- }
- Reader thread functions
- unsigned int __stdcall readerthreadfun (PVOID pM)
- {
- readerprintf ("%d reader entered wait ... \ n", GetCurrentThreadID ());
- //Wait for the writer to complete
- WaitForSingleObject (G_heventwriter, INFINITE);
- //number of readers increased
- EnterCriticalSection (&g_cs_writer_count);
- g_nreadercount++;
- if (G_nreadercount = = 1)
- ResetEvent (G_heventnoreader);
- LeaveCriticalSection (&g_cs_writer_count);
- //Read file
- readerprintf ("%d reader starts reading files ... \ n", GetCurrentThreadID ());
- Sleep (rand ()% 100);
- //End reading, number of readers decreased, vacancy increased
- readerprintf ("%d reader ends reading file \ n", GetCurrentThreadID ());
- //number of readers decreased
- EnterCriticalSection (&g_cs_writer_count);
- g_nreadercount--;
- if (G_nreadercount = = 0)
- SetEvent (G_heventnoreader);
- LeaveCriticalSection (&g_cs_writer_count);
- return 0;
- }
- Writer thread output function
- void writerprintf (char *pszstr)
- {
- EnterCriticalSection (&g_cs);
- Setconsolecolor (Foreground_green);
- printf ("%s\n", pszstr);
- Setconsolecolor (foreground_red | Foreground_green | Foreground_blue);
- LeaveCriticalSection (&g_cs);
- }
- Writer thread functions
- unsigned int __stdcall writerthreadfun (PVOID pM)
- {
- writerprintf ("writer thread enters wait ...");
- //Waiting for the reader to read the file is zero
- WaitForSingleObject (G_heventnoreader, INFINITE);
- //Mark writer is writing file
- ResetEvent (G_heventwriter);
- //write file
- writerprintf ("writer begins to write files ...");
- Sleep (rand ()% 100);
- writerprintf ("writer finishes writing documents");
- //Mark writer end Write file
- SetEvent (G_heventwriter);
- return 0;
- }
- int main ()
- {
- printf ("reader Writer's question \ n");
- printf ("-by Morewindows (http://blog.csdn.net/MoreWindows)--\n\n");
- //Initialize events and semaphores
- InitializeCriticalSection (&g_cs);
- InitializeCriticalSection (&g_cs_writer_count);
- //manual position, initial trigger
- G_heventwriter = CreateEvent (null, True, true, null);
- G_heventnoreader = CreateEvent (null, FALSE, TRUE, NULL);
- G_nreadercount = 0;
- int i;
- HANDLE Hthread[reader_num + 1];
- //Start two reader threads first
- For (i = 1; I <= 2; i++)
- Hthread[i] = (HANDLE) _beginthreadex (null, 0, readerthreadfun, NULL, 0, NULL);
- //Start writer thread
- Hthread[0] = (HANDLE) _beginthreadex (null, 0, writerthreadfun, NULL, 0, NULL);
- Sleep (50);
- ///finally start other reader processes
- For (; I <= reader_num; i++)
- Hthread[i] = (HANDLE) _beginthreadex (null, 0, readerthreadfun, NULL, 0, NULL);
- WaitForMultipleObjects (Reader_num + 1, hthread, TRUE, INFINITE);
- For (i = 0; i < Reader_num + 1; i++)
- CloseHandle (Hthread[i]);
- //Destroy events and semaphores
- CloseHandle (G_heventwriter);
- CloseHandle (G_heventnoreader);
- DeleteCriticalSection (&g_cs);
- DeleteCriticalSection (&g_cs_writer_count);
- return 0;
- }
The results of the operation are as follows:
The result shows that when a reader reads a file, the writer thread goes into the wait state. When the writer thread writes a file, the reader thread waits, indicating that the reader and the writer have completed the synchronization.
This series throughClassic thread Synchronization issuesto enumerate the key segments , events , mutexes , and semaphores of thread synchronization methods, And the four methods are summarized . Then through two well-known thread synchronization instance- producer consumer problem and reader writer problem to strengthen the understanding and application of multi-thread synchronization mutex. Hope that readers can master, so that in the written interview can be a smooth "second-kill" multi-threaded related questions, to obtain their own satisfactory offer .
From the second multi-threaded tenth producer consumer problem to the second-kill multi-threaded 11th reader writer Problem can be concluded that the key to multi-threaded problem is to find all the "wait" situation and determine whether there is no need for mutually exclusive access to resources. So how do you find these better, faster and more comprehensively from the actual problem? Take a look at the second multi-threaded 12th Multi- threaded synchronous internal Heart--PV operation and the second kill multithreading 13th Multi-threaded synchronous internal heart--PV operation These two to strengthen the solution of multi-threaded synchronization problem "internal".
In addition, reader Writer's question can be solved with read-write lock srwlock, please see "second-order multi-threaded 14th reader Writer's question" Read and write lock Srwlock"
Reprint please indicate source, original address: http://blog.csdn.net/morewindows/article/details/7596034
Turn---seconds to kill multithreading 11th reader Writer's question