本博客代码摘自Mic_H,我小小地修改了一些。
本博客记录自己的学习,疑问和理解。欢迎大家交流和指教。
作者原博客链接
我的代码和运行结果:

#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <accctrl.h>
#include <time.h>
unsigned int readcount = 0;
bool p_ccontinue = true; //控制程序结束
HANDLE RSemaphore; //改变readcount值时互斥
HANDLE WSemaphore; //写互斥
DWORD WINAPI Writer(LPVOID); //写者线程
DWORD WINAPI Reader(LPVOID); //读者线程
int main()
{RSemaphore = CreateSemaphore(NULL,1,1,NULL);WSemaphore = CreateSemaphore(NULL,1,1,NULL);const unsigned short Writer_COUNT = 3;//写者数量const unsigned short Reader_COUNT = 8;//读者数量const unsigned short THREADS_COUNT = Writer_COUNT+Reader_COUNT;HANDLE hThreads[THREADS_COUNT]; //各线程的 handleDWORD writerID[Writer_COUNT]; //写者线程的标识符DWORD readerID[Reader_COUNT]; //读者线程的标识符srand(time(0));int writer_count = 0;int reader_count = 0;for(int i = 0; i < Writer_COUNT + Reader_COUNT; i++){int ran = rand()%10;if((ran < 5) && (writer_count < Writer_COUNT))//Writer{hThreads[i]=CreateThread(NULL,0,Writer,NULL,0,&writerID[writer_count]);if (hThreads[i]==NULL) return -1;writer_count++;}else if((ran >= 5) && (reader_count < Reader_COUNT))//Reader{hThreads[i]=CreateThread(NULL,0,Reader,NULL,0,&readerID[reader_count]);if (hThreads[i]==NULL) return -1;reader_count++;}Sleep(500);//等待500ms}while(p_ccontinue){if(getchar())  //按回车后终止程序运行{p_ccontinue = false;}}return 0;
}
//写者
DWORD WINAPI Writer(LPVOID lpPara)
{while(p_ccontinue){printf("\n%d is waiting to write...\n",GetCurrentThreadId());WaitForSingleObject(WSemaphore,INFINITE);//P(w)在读或在写时,写者阻塞printf("\n**  writer %d got the control\n",GetCurrentThreadId());//write...printf("\n%d is writing...\n",GetCurrentThreadId());Sleep(1500);printf("\n--- %d have finished the writing\n",GetCurrentThreadId());ReleaseSemaphore(WSemaphore,1,NULL);//V(w)写完,唤醒阻塞的读者或写者return 0;//结束此线程}return 0;
}
//读者
DWORD WINAPI Reader(LPVOID lpPara)
{while(p_ccontinue){printf("\n%d is waiting to read...\n",GetCurrentThreadId());WaitForSingleObject(RSemaphore,INFINITE);//P(x)临界区互斥,所有读者修改readcountreadcount++;if(readcount == 1)//第一个读,要等已经在写的写者写完才可以开始读WaitForSingleObject(WSemaphore,INFINITE);//P(w)有写时,读者阻塞//同时读,故要在Read()之前V(x)ReleaseSemaphore(RSemaphore,1,NULL);//V(x)//read...printf("\n%d is reading...\n",GetCurrentThreadId());Sleep(1500);printf("\n--- %d have finished the reading\n",GetCurrentThreadId());WaitForSingleObject(RSemaphore,INFINITE);//P(x)readcount--;if(readcount== 0){printf("\n----- All Readers done\n");ReleaseSemaphore(WSemaphore,1,NULL);//V(w)都不读,唤醒阻塞的写者}ReleaseSemaphore(RSemaphore,1,NULL);//V(x)return 0;//结束此线程}return 0;
}

13656 is waiting to write...**  writer 13656 got the control13656 is writing...33596 is waiting to read...7620 is waiting to read...--- 13656 have finished the writing33596 is reading...33596 is reading...7620 is reading...29964 is waiting to read...29964 is reading...31876 is waiting to write...34616 is waiting to read...34616 is reading...--- 33596 have finished the reading--- 33596 have finished the reading--- 29964 have finished the reading--- 33596 have finished the reading--- 29964 have finished the reading
--- 7620 have finished the reading32608 is waiting to read...32608 is reading...7800 is waiting to write...--- 34616 have finished the reading--- 32608 have finished the reading----- All Readers done**  writer 31876 got the control31876 is writing...--- 31876 have finished the writing**  writer 7800 got the control7800 is writing...--- 7800 have finished the writing

以下是我自己实验的一些薄浅的理解和疑问(本人小白,写错了不要喷,欢迎大家指教)。
理解:1.通过srand获得随机数种子,ran获得随机数,经if语句的两个条件,决定创建是写线程还是读线程。但是这个for循环i是小于3+8的,如果write_count为3,即写线程创建完成了,但是此后有一个或者几个ran<5,既不会创建写线程,也不会创建读线程。所以不会创建8个读线程,大概率会小于8个读线程。(运行20次左右就出现一次)
2.写线程中的ReleaseSemaphore(WSemaphore,1,NULL)唤醒的是阻塞的读者或写者。我修改之后的程序运行,如果xxxx is waiting to read 在 xxxx is waiting 之前,这个写线程是先被调度的,所以先输出xxxx is writing 后输出 xxxx is reading。注意:绝对读者优先此处唤醒的是阻塞的读者。
3.sleep(500)可以表示写、读线程进入的过程。sleep(1500)可以表示写线程写的过程,读线程读的过程。
疑问:
1.for循环中的Writer_COUNT + Reader_COUNT改成THREADS_COUNT(极少时候没改变这个也会出现),部分xxxx is reading就会输出两次,但是xxxx is waiting to read只出现一次。(如图的33596就是这样)这个疑问不知道是怎么回事。读线程和写线程函数部分,我加了一些单词或者换成中文,前几次运行结果均会出现乱码,格式错误等问题,多运行几次后,每4.5次就会出现一次乱码(估计可能是我vc6++是中文破译版的问题)。
因为是刚刚学习操作系统中各种问题的代码实现,就有很多系统函数不知道。所以我做了一些笔记(字难看,勿喷),


读者写者问题读者优先 C语言实现代码相关推荐

  1. 读者写者模型---读优先与写优先

    Linux线程中写过生产者消费者模型,这次研究读者写者模型. 文章目录 读者写者模型遵循的规则 读者优先 写者优先 读者和写者公平竞争 读者写者模型遵循的规则 读者-写者模型同样遵循321规则: 写- ...

  2. Java实现读者写者问题--读者优先

    作者:凌杰林 简介 临界资源:同一时间只能由一个进程访问的资源 临界区:访问临界资源的代码段 读者写者问题:存在一个多个进程共享的数据区(临界资源),该数据区可以是一个文件或者一块内存空间,甚至可以是 ...

  3. 操作系统 读者写者问题的实现(C++ 读者优先、写者优先)

    通过信号量机制和相应的系统调用,用于线程的互斥和同步,实现读者写者问题.利用信号量机制,实现读者写者问题. 在windows 10环境下,创建一个控制台进程,此进程包含n个线程.用这n个线程来表示n个 ...

  4. 读者写者问题(读者优先)

    一.读者写者问题定义 存在一个多个进程共享的数据区,该数据区可以是一个文件或一块内存空间,甚至可以是一组寄存器:有些进程(reader)只读取这个数据区中的数据,有些进程(writer)只往数据区中写 ...

  5. java 读者写者_Java实现生产者消费者问题与读者写者问题详解

    1.生产者消费者问题 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品.解决生产者/消费者问题的方法可分为两 ...

  6. java实现带界面的生产者消费者_Java实现生产者消费者问题与读者写者问题

    1.生产者消费者问题 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品.解决生产者/消费者问题的方法可分为两 ...

  7. Java 5种方法实现生产者消费者问题与2种方法实现读者写者问题

    摘要: Java实现生产者消费者问题与读者写者问题 1.生产者消费者问题 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从 ...

  8. Linux多线程实践(6) --Posix读写锁解决读者写者问题

    Posix读写锁 int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,const pthread_rwlockattr_t *restr ...

  9. 【操作系统/OS笔记14】经典同步问题:读者-写者问题、哲学家就餐问题

    本次笔记内容: 10.6 经典同步问题-1 10.7 经典同步问题-2 10.8 经典同步问题-3 10.9 经典同步问题-4 10.10 经典同步问题-5 10.11 经典同步问题-6 文章目录 读 ...

最新文章

  1. 关卡设计快速入门_5. 编辑已放置的Actor
  2. 安全检测点的一些梳理——待长期整理
  3. c++ 深度优先搜索(迷宫)
  4. autossh端口映射
  5. 长庆企业信息化管理课件_详解:企业信息化管理系统,不能马虎对待
  6. 计算机网络怎么查看连接打印机驱动,涨姿势:手把手教你如何连接网络打印机...
  7. 数据结构之查找算法:散列查找
  8. php7.2连接mysql8_兼容 php 7.2 及 mysql 8
  9. Pecl和Pear的区别和联系?
  10. win11右键菜单怎么修改 Windows11修改右键菜单为win10风格的步骤方法
  11. Date类的getYear(),getMonth过时,现在的获取方法
  12. windows版redis报错:本地计算机上的Redis服务启动后停止
  13. 守卫数据中心命门的胡桃夹子-特权账号管理平台
  14. 使用后端解析地图.shp.prj文件得到GeoJson数据
  15. Android 最常用的设计模式十 安卓源码分析——策略模式(Strategy)
  16. linux 使用samba共享文件夹
  17. chmod 777的含义
  18. 【流媒体服务器Mediasoup】多人音视频架构、流媒体的比较、mediasoup介绍 (一)
  19. java实现地图导航功能吗_Java web实现百度地图导航
  20. IDEA中快速添加自己自定义的方法方法,想要什么快捷方法都行

热门文章

  1. 利用xss平台的payload输入留言即可获得flag
  2. java对象赋值给数组_带你深入的理解数组和对象的解构赋值。
  3. 200 亿美元,Adobe 为何看好这家创业十年的软件设计公司?
  4. Winform UI界面设计例程(二)主题风格切换
  5. 如何显示隐藏的文件、文件夹或者驱动器
  6. Dollar Dayz(完全背包 + 高精度)
  7. suse linux 如何修改主机名,就这样轻松在Suse修改主机名
  8. 浏览器上传附件或者下载导致浏览器直接卡死(无响应)的解决方案
  9. Android动画学习记录一(Android动画种类、补间动画和帧动画)
  10. 深入理解C++中的move和forward!