多线程例子—作家,读者问题
来源:互联网 发布:淘宝客店铺推广佣金 编辑:程序博客网 时间:2024/04/30 22:38
读者写者问题描述非常简单,有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者在读文件时写者也不去能写文件。
首先来找找哪些是属于“等待”情况。
第一.写者要等到没有读者时才能去写文件。
第二.所有读者要等待写者完成写文
件后才能去读文件。
找完“等待”情况后,再看看有没有要互斥访问的资源。由于只有一个写者,所以只有一篇文章,而读者们是可以共享的读文件,所以按题目要求并没有需要互斥访问的资源。()
解决了互斥输出问题,接下来再考虑如何实现同步问题。可以设置一个变量来记录正在读文件的读者个数,第一个开始读文件的读者要负责将关闭允许写者进入的标志,最后一个结束读文件的读者要负责打开允许写者进入的标志。这样第一种“等待”情况就解决了。第二种“等待”情况是有写者进入时所以读者不能进入,使用一个事件就可以完成这个任务了——所有读者都要等待这个事件而写者负责触发事件和设置事件为未触发。
//<读者与写者问题#include <stdio.h>#include <process.h>#include <windows.h>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_list指向参数的指针va_start(pArgList, pszFormat);EnterCriticalSection(&g_cs);vfprintf(stdout, pszFormat, pArgList);LeaveCriticalSection(&g_cs);va_end(pArgList);}//<写者线程输出函数void WriterPrintf(char *pszStr){EnterCriticalSection(&g_cs);printf(" %s\n", pszStr);LeaveCriticalSection(&g_cs);}//<读者线程函数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;}//<写者线程函数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( http://blog.csdn.net/MoreWindows ) --\n\n");//<初始化事件和信号量InitializeCriticalSection(&g_cs);InitializeCriticalSection(&g_cs_writer_count);//<手动置位,初始已触发g_hEventWriter = CreateEvent(NULL, TRUE, TRUE, NULL); //<第二个参数true为手动置位,因为所有读者可以共享一篇文章g_hEventNoReader = CreateEvent(NULL, FALSE, TRUE, NULL); //<第二个参数为false为自动置位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;}
0 0
- 多线程例子—作家,读者问题
- 多线程例子—读者,作家使用读写锁(SRWLOCK)
- 多线程---读者写者问题
- Java 多线程读者写者问题
- 多线程练习----读者写者问题
- 多线程的读者写者问题
- 多线程11:读者写者问题
- 多线程_-读者写者问题
- <MFC多线程> 读者写者问题
- Windows多线程 经典读者写着问题
- 【多线程】(十)读者写者问题
- JAVA多线程实现读者写者问题
- 秒杀多线程-读者写者问题
- 读者写者问题(Java多线程)
- 多线程同步问题中,读者——写者问题,iOS实现。
- 多线程经典问题之读者、写者问题
- Java 多线程问题例子
- 秒杀多线程第十一篇 读者写者问题
- 0c中各种数据类型的转换方法
- 原来中文编程就是这样的。。
- SQL Union和SQL Union All用法
- 操作系统内存管理之内部碎片 与外部碎片
- Windows 8(64位)如何搭建 Android 开发环境与真机测试
- 多线程例子—作家,读者问题
- 才法规和地方和反对回复的机会发过节费
- HDU-3555 Bomb
- UILabel, UITextField, UIButton
- HDU 4970
- 黑马程序员---property用法
- windows下使用memcache并修改memcache最大使用内存
- Mac系统上GoAgent的安装和使用
- iOS App进入后台获取更多的运行时间