秒杀多线程第十一篇 读者写者问题

//读者线程输出函数void ReaderPrintf(char *pszFormat, …){va_list pArgList;va_start(pArgList, pszFormat);EnterCriticalSection(&g_cs);vfprintf(stdout, pszFormat, pArgList);LeaveCriticalSection(&g_cs);va_end(pArgList);}//写者线程输出函数void WriterPrintf(char *pszStr){EnterCriticalSection(&g_cs);SetConsoleColor(FOREGROUND_GREEN);printf("%s\n", pszStr);SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);LeaveCriticalSection(&g_cs);}

解决了互斥输出问题,,接下来再考虑如何实现同步问题。可以设置一个变量来记录正在读文件的读者个数,第一个开始读文件的读者要负责将关闭允许写者进入的标志,最后一个结束读文件的读者要负责打开允许写者进入的标志。这样第一种“等待”情况就解决了。第二种“等待”情况是有写者进入时所以读者不能进入,使用一个事件就可以完成这个任务了——所有读者都要等待这个事件而写者负责触发事件和设置事件为未触发。详细见代码中注释:

//读者与写者问题#include <stdio.h>#include <process.h>#include <windows.h>//设置控制台输出颜色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; //读者个数//关键段和事件CRITICAL_SECTION g_cs, g_cs_writer_count;HANDLE g_hEventWriter, g_hEventNoReader;int g_nReaderCount;//读者线程输出函数(变参函数的实现)void ReaderPrintf(char *pszFormat, …){va_list pArgList;va_start(pArgList, pszFormat);EnterCriticalSection(&g_cs);vfprintf(stdout, pszFormat, pArgList);LeaveCriticalSection(&g_cs);va_end(pArgList);}//读者线程函数unsigned int __stdcall ReaderThreadFun(PVOID pM){ReaderPrintf("编号为%d的读者进入等待中…\n", GetCurrentThreadId());//等待写者完成WaitForSingleObject(g_hEventWriter, INFINITE);//读者个数增加EnterCriticalSection(&g_cs_writer_count);g_nReaderCount++;if (g_nReaderCount == 1)ResetEvent(g_hEventNoReader);LeaveCriticalSection(&g_cs_writer_count);//读取文件ReaderPrintf("编号为%d的读者开始读取文件…\n", GetCurrentThreadId());Sleep(rand() % 100);//结束阅读,读者个数减小,空位增加ReaderPrintf(" 编号为%d的读者结束读取文件\n", GetCurrentThreadId());//读者个数减少EnterCriticalSection(&g_cs_writer_count);g_nReaderCount–;if (g_nReaderCount == 0)SetEvent(g_hEventNoReader);LeaveCriticalSection(&g_cs_writer_count);return 0;}//写者线程输出函数void WriterPrintf(char *pszStr){EnterCriticalSection(&g_cs);SetConsoleColor(FOREGROUND_GREEN);printf("%s\n", pszStr);SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);LeaveCriticalSection(&g_cs);}//写者线程函数unsigned int __stdcall WriterThreadFun(PVOID pM){WriterPrintf("写者线程进入等待中…");//等待读文件的读者为零WaitForSingleObject(g_hEventNoReader, INFINITE);//标记写者正在写文件ResetEvent(g_hEventWriter);//写文件WriterPrintf(" 写者开始写文件…..");Sleep(rand() % 100);WriterPrintf(" 写者结束写文件");//标记写者结束写文件SetEvent(g_hEventWriter);return 0;}int main(){printf(" 读者写者问题\n");printf(" — by MoreWindows( ) –\n\n");//初始化事件和信号量InitializeCriticalSection(&g_cs);InitializeCriticalSection(&g_cs_writer_count);//手动置位,初始已触发g_hEventWriter = CreateEvent(NULL, TRUE, TRUE, NULL);g_hEventNoReader = CreateEvent(NULL, FALSE, TRUE, NULL);g_nReaderCount = 0;int i;HANDLE hThread[READER_NUM + 1];//先启动二个读者线程for (i = 1; i <= 2; i++)hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL);//启动写者线程hThread[0] = (HANDLE)_beginthreadex(NULL, 0, WriterThreadFun, NULL, 0, NULL);Sleep(50);//最后启动其它读者结程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]);//销毁事件和信号量CloseHandle(g_hEventWriter);CloseHandle(g_hEventNoReader);DeleteCriticalSection(&g_cs);DeleteCriticalSection(&g_cs_writer_count);return 0;}

读者写者问题

转载请标明出处,原文地址:

你并不一定会从此拥有更美好的人生,

秒杀多线程第十一篇 读者写者问题

相关文章:

你感兴趣的文章:

标签云: