完整代码实现:

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <time.h>
  4. #include <stdlib.h>
  5. #include <pthread.h>
  6. #include <semaphore.h>
  7. #define TOTAL_NUMBER 20
  8. void *writer(void *param);
  9. void *reader(void *param);
  10. int reader_num = 0;
  11. int writer_num = 0;
  12. int reader_mutex = 0;
  13. int unit[TOTAL_NUMBER] = {0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0};
  14. sem_t wmutex;
  15. sem_t mutex;
  16. int main(int argc, char *argv[]) {
  17. sem_init(&mutex,0,1);
  18. sem_init(&wmutex,0,1);
  19. for (int i = 0; i < TOTAL_NUMBER; i++){
  20. sleep(1);
  21. time_t t = time(NULL);
  22. struct tm tm = *localtime(&t);
  23. if(unit[i] == 0){
  24. pthread_t thread_id;
  25. pthread_create(&thread_id, NULL, reader, NULL);
  26. reader_num ++;
  27. printf("%d:%d:%d: Creating %dth reader.\n", tm.tm_hour, tm.tm_min, tm.tm_sec, reader_num);
  28. }else{
  29. pthread_t thread_id;
  30. pthread_create(&thread_id, NULL, writer, NULL);
  31. writer_num ++;
  32. printf("%d:%d:%d: Creating %dth writer.\n", tm.tm_hour, tm.tm_min, tm.tm_sec, writer_num);
  33. }
  34. }
  35. }
  36. void *reader(void *param) {
  37. time_t t = time(NULL);
  38. struct tm tm = *localtime(&t);
  39. printf("%d:%d:%d: NO.%u reader requires reading.\n", tm.tm_hour, tm.tm_min, tm.tm_sec, pthread_self());
  40. sem_wait(&mutex);
  41. reader_mutex ++;
  42. if(reader_mutex == 1){
  43. sem_wait(&wmutex);
  44. }
  45. sem_post(&mutex);
  46. // Read data
  47. t = time(NULL);
  48. tm = *localtime(&t);
  49. printf("%d:%d:%d: NO.%u reader begins to read.\n", tm.tm_hour, tm.tm_min, tm.tm_sec, pthread_self());
  50. sleep(1);
  51. t = time(NULL);
  52. tm = *localtime(&t);
  53. printf("%d:%d:%d: End of NO.%u reader for reading.\n", tm.tm_hour, tm.tm_min, tm.tm_sec, pthread_self());
  54. sem_wait(&mutex);
  55. reader_mutex --;
  56. if(reader_mutex == 0){
  57. sem_post(&wmutex);
  58. }
  59. sem_post(&mutex);
  60. }
  61. void *writer(void *param) {
  62. time_t t = time(NULL);
  63. struct tm tm = *localtime(&t);
  64. printf("%d:%d:%d: NO.%u writer requires writing.\n", tm.tm_hour, tm.tm_min, tm.tm_sec, pthread_self());
  65. sem_wait(&wmutex);
  66. // Write data
  67. t = time(NULL);
  68. tm = *localtime(&t);
  69. printf("%d:%d:%d: NO.%u writer begins to write.\n", tm.tm_hour, tm.tm_min, tm.tm_sec, pthread_self());
  70. sleep(6);
  71. t = time(NULL);
  72. tm = *localtime(&t);
  73. printf("%d:%d:%d: End of NO.%u writer for writing.\n", tm.tm_hour, tm.tm_min, tm.tm_sec, pthread_self());
  74. sem_post(&wmutex);
  75. }

IPC 经典问题:Reader & Writer Problem的更多相关文章

  1. RFID 读写器 Reader Writer Cloner

    RFID读写器的工作原理 RFID的数据采集以读写器为主导,RFID读写器是一种通过无线通信,实现对标签识别和内存数据的读出和写入操作的装置. 读写器又称为阅读器或读头(Reader).查询器(Int ...

  2. RFIDler - An open source Software Defined RFID Reader/Writer/Emulator

    https://www.kickstarter.com/projects/1708444109/rfidler-a-software-defined-rfid-reader-writer-emul h ...

  3. Stream,Reader/Writer,Buffered的区别(1)

    Stream: 是字节流形式,exe文件,图片,视频等.支持8位的字符,用于 ASCII 字符和二进制数据. Reader/Writer: 是字符流,文本文件,XML,txt等,用于16位字符,也就是 ...

  4. RubyMine生成reader/writer方法

    RubyMine生成reader/writer方法 在非类的ruby文件中,Alt+Insert会出现新建文件的选项: 在ruby文件的类中,Alt+Insert会出现get/set方法生成提示和重构 ...

  5. IPC 经典问题:Sleeping Barber Problem

    完整代码实现: #include <stdio.h> #include <unistd.h> #include <time.h> #include <stdl ...

  6. multithreading - Reader/Writer Locks in C++

    You Only Need To Note This: only 1 single thread can acquire an upgrade_lock at one time. others are ...

  7. Stream,Reader/Writer,Buffered的区别(2)

    Reader: Reader的子类: 1.BufferedReader: FileReader 没有提供读取文本行的功能,BufferedReader能够指定缓冲区大小,包装了read方法高效读取字符 ...

  8. ExtJS4.2学习(7)——基础知识之Reader&Writer篇

    Reader: 主要用于将proxy数据代理读取的数据按照不同的规则进行解析,将解析好的数据保存到Modle中. 结构图 Ext.data.reader.Reader 读取器的根类(很少直接实例化这个 ...

  9. 02_IO操作的基本规律(InputStream,OutputStream,Reader,Writer,FileReader,FileWriter,BufferedReader,BufferedWri

     模拟BufferedInputStream,编写一个类 package toto.IO; import java.io.IOException; import java.io.InputStre ...

随机推荐

  1. SpringBoot 拦截器和自定义注解判断请求是否合法

    应用场景举例: 当不同身份的用户请求一个接口时,用来校验用户某些身份,这样可以对单个字段数据进行精确权限控制,具体看代码注释 自定义注解 /** * 对比请求的用户身份是否符合 * @author l ...

  2. Linux下基于.NET5开发CAX应用

    <<.NET5下的三维应用程序开发>>一文中介绍了如何在.NET5下使用AnyCAD开发应用程序.相比.NET4.x,.NET5一大进步便是可以跨平台,即可以在Linux.Ma ...

  3. 我叫Mongo,干了「索引探索篇」提升我的效率,值得您拥有

    这是mongo第四篇"索引探索",后续会连续更新4篇 mongodb的文章总结上会有一系列的文章,顺序是先学会怎么用,在学会怎么用好,戒急戒躁,循序渐进,跟着我一起来探索交流.通过 ...

  4. ReentrantReadWriterLock源码(state设计、读写锁、共享锁、独占锁及锁降级)

    ReentrantReadWriterLock 读写锁类图(截图来源https://blog.csdn.net/wangbo199308/article/details/108688148) stat ...

  5. Vue3 使用 svg-sprite-loader 实现 svg 图标按需加载

    前面文章有讲到 svg 图标按需加载的优势以及 Vue 如何使用 vue-svg-icon 实现 svg 图标按需载入: https://www.cnblogs.com/Leophen/p/13201 ...

  6. 利用Python将PDF文档转为MP3音频

    1. 转语音工具 微信读书有一个功能,可以将书里的文字转换为音频,而且声音优化的不错,比传统的机械朗读听起来舒服很多. 记得之前看到过Python有一个工具包,可以将文字转换为语音,支持英文和中文,而 ...

  7. ASP.NET网站部署到服务器IIS上和本地局域网服务器

    控制面板>>>管理工具>>>打开Internet信息服务 2,如果找不到 可以控制面板>>>程序和功能>>>  打开或关闭win ...

  8. Telegraf+Influxdb+Grafana自动化运维监控

    概述:Telegraf收集信息,influxdb时序数据库存储数据,grafana平台展示数据,并进行监控告警,组成一个自动化运维监控平台. 一.influxdb ​ InfluxDB是一个由Infl ...

  9. Minor GC 和 Full GC的时机

    一.对象何时能够进入老年代 GC年龄判定 每进行一次GC过程,存活的对象的GC年龄都会+1:当对象逃过15次GC,年龄达到15岁时,即可进入老年代 可以通过-XX:MaxTenuringThreshl ...

  10. alibaba-sentinel-1.8变化

    maven最新坐标 <dependencies> <dependency> <groupId>org.springframework.boot</groupI ...