读者——写者问题 (转)

读者——写者问题 (转)[@more@]

#include XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />

#include <windows.h>

 

#include "Reader-Writer.h"

#include "Semaphore.h"

 

// 这是 Windows 下多线程工作的 P 操作

#define P(S) WaitForSingleobject(S, INFINITE)

 

// 这是 Windows 下多线程工作的 V 操作

#define V(S) ReleaseSemaphore(S, 1, NULL)

 

const int RN = 5; // 所有读者总数

const int WN = 3; // 所有写者总数

 

HANDLE Sdoc; // 文档信号量——互斥量

HANDLE Sr;  // 读者信号量——广义信号量

 

HANDLE Scnt; // 保护 g_cntReader 的互斥量

int g_cntReader = 0; // 读者个数计数器

 

// ##############+. Descripted By Tang Houjian [2003-9-26 20:10:49] .+##########

// |  funcname  :  JustWait ( )

// +  note  :  显示一些信息,让后等待

// | 

// +-----------------------------------------------------------------+

// |  ret val  :  void

// | 

// +  Parameter : 

// |  [  int ] - nReader 读者(写者)编号,读者>0,写者<0

// |  [  int ] - min  操作等待的最短时间

// |  [  int ] - max  操作等待得最长时间,实际等待的时间介于两者之间

// |  [ LPCSTR ] - info  要显示的信息

void JustWait(int nReader, int min, int max, LPCSTR info)

// +-----------------------------------------------------------------+

{

  // 等待时间的基本量,以毫秒表示

  const int BASETIME = 1000;

 

  // 实际等待得时间

  int wait_time = 0;

  if (max==min)  // 判断是为了避免 %0错误,注意取随机值

    wait_time = min*BASETIME;

  else

    wait_time = rand()%(max*BASETIME-min*BASETIME) + min*BASETIME;

 

  // 最终显示的信息缓冲

  char s_out[128];

 

  // 读者大于0,写者小于0

  if (nReader > 0)

    sprintf(s_out, "Reader [%d]: %sn", nReader, info);

  else

    sprintf(s_out, "tWriter [%d]: %sn", -nReader, info);

 

  // 打印

  printf(s_out);

 

  // 然后等待

  Sleep(wait_time);

}

 

// 这是主函数

void TryReaderAndWriter()

{

  // 创建信号量  这是初值--+  +----这是最大信号量值

  //  |  |

  Sdoc = CreateSemaphore(NULL, 1, 1, "Document");

 

  // 一次最多允许 3 个读者读

  Sr = CreateSemaphore(NULL, 3, 3, "ReaderNumber");

 

  // 他也是一个互斥信号量,初值为 1

  Scnt = CreateSemaphore(NULL, 1, 1, "ReaderCounterProtect");

 

  // 线程句柄

  HANDLE threads[RN+WN];

 

  // 创建读者线程,共有 RN 个读者

  for (int i=0; i

    threads[i] = CreateThread(0, 0, Reader, 0, 0, 0);

 

  // 创建写者线程,共有 WN 个写者

  for (int j=0; j

    threads[j+RN] = CreateThread(0, 0, Writer, 0, 0, 0);

 

  WaitForMultipleObjects(RN+WN, threads, TRUE, INFINITE);

}

 

// 读者线程

Dword WINapi Reader(LPVOID lpPara)

{

  // 注意是静态变量,可以使每来一个读者增加一

  static int reader_num = 1;

  int i = reader_num ++;

 

  while (1)

  {

    JustWait(i, 1, 2, "I want to Read");

 

  // 读者未满

    P(Sr);

 

  // 锁定读者计数器

    P(Scnt);

    printf("//: %d Readers in, [%d] inn”, g_cntReader, i);

    g_cntReader ++;

  // 如果是第一个读者

  if (g_cntReader == 1)

  {

    JustWait(i, 1, 2, "I am NUMBER-ONE!");

    // 锁定文档

    P(Sdoc);

    printf("#----------[%d] <== Doc busyn", i);

    JustWait(i, 1, 2, "I have get the document");

  }

  // 解锁读者计数器

    V(Scnt);

 

  // ing…………

    JustWait(i, 2, 5, "I am reading...");

 

    JustWait(i, 1, 2, "I want to get out");

 

  // 锁定读者计数器

    P(Scnt);

    g_cntReader --;

  // 如果是最后一个

  if (g_cntReader == 0)

  {

    JustWait(i, 1, 2, "I am the LAST-ONE!");

    printf("----------#[%d] ==> Doc freen", i);

    // 解锁文档

    V(Sdoc);

  }

    printf("//: %d Readers Left, [%d] is outn”, g_cntReader, i);

  // 解锁读者计数器

    V(Scnt);

 

  // 离开

    V(Sr);

 

    JustWait(i, 5, 3, "Rest^^^^^^^^^^^^");

  }

 

  return 0;

}

DWORD WINAPI Writer(LPVOID lpPara)

{

  // 注意是静态变量,可以使每来一个写者减去一,注意初值是负值

  static int g_cnt = -1;

  int j = g_cnt --;

 

  while (1)

  {

    JustWait(j, 2, 4, "I want write...");

 

  // 锁定文档

    P(Sdoc);

    printf("t#==========[%d] <== Doc busyn", -j);

 

  // ing……

    JustWait(j, 4, 3, "WRITING......");

 

    JustWait(j, 1, 2, "write over! Out");

    printf("t==========#[%d] ==> Doc freen", -j);

 

  // 解锁文档

    V(Sdoc);

    JustWait(j, 8, 4, "Rest~~~~~~~~~~~~~");

  }

 

  return 0;

}

 


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-998117/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752043/viewspace-998117/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
初始条件: 1操作系统:Linux 或者 windows 2程序设计语言:C,java语言 3设有20个连续的存储单元,写入/读出的数据项按增序设定为1-20这20个字符。 要求完成的主要任务: (包括课程设计工作量及其技术要求,以及说明书撰写等具体要求) 1.技术要求: 1)为每个读者写者产生一个线程,设计正确的同步算法 2)每个读者/写者对该存储区进行操作后,即时显示该存储区的全部内容、当前指针位置和读者/写者线程的自定义标识符。。 3)读者应有3个以上,写者应有有两个以上。 4)多个读者/写者之间须共享对存储区进行操作的函数代码。 2. 设计说明书内容要求: 1)设计题目与要求 2)总的设计思想及系统平台、语言、工具等。 3)数据结构与模块说明(功能与流程图) 4)给出用户名、源程序名、目标程序名和源程序及其运行结果。(要注明存储各个程序及其运行结果的主机IP地址和目录。) 5)运行结果与运行情况 (提示: (1)连续存储区可用数组实现。 (2)编译命令可用:     cc -lpthread -o  目标文件名  源文件名 (3)多线程编程方法参见附件。) 3. 调试报告: 1) 调试记录 2) 自我评析和总结 上机时间安排: 19周一 ~ 五 下午14:00 - 18:00 (6月27日开始) 指导教师签名: 年 月 日 系主任(或责任教师)签名: 年 月 日 五、源代码 #include #include #include "fstream.h" int readcount=0; //读者数目 int writecount=0; //写者数目 CRITICAL_SECTION RP_Write; //临界区 CRITICAL_SECTION cs_Write; CRITICAL_SECTION cs_Read; struct ThreadInfo //线程信息 { int Threadhao; //线程序号 char ThreadClass; //线程类别 double ThreadStartTime; //线程开始时间 double ThreadRunTime; //线程读写持续时间 }; void ReaderFun(char* file);//读者优先函数 void R_ReaderThread(void *p);//处理读者优先读者线程 void R_WriterThread(void *p);//处理读者优先写者线程 void WriterFun(char* file); void W_ReaderThread(void *p); void W_WriterThread(void *p); int main()//主函数 { char select; while (true) { cout<<"***************本程序实现读者-写者问题*******\n"<<endl; cout<<" 1:读者优先"<<endl; cout<<" 2:写者优先"<<endl; cout<<" 3:退出"<<endl; cout<<"\n*********************************************"<<endl; cout<<"请选择要进行的操作:"<>select; if(select!='1' && select!='2' && select!='3') cout<<"你操作有误,请重试!"<<endl; }while (select!='1' && select!='2' && select!='3'); system("cls"); if (select=='3') return 0;//退出 else if (select=='1')//调用读者优先 ReaderFun("peizhi.txt"); else if(select=='2')//调用写者优先 WriterFun("peizhi.txt"); cout<<"\n是否还有继续? 1. 继续 2.退出"<>select; if(select!='1' && select!='2' ) cout<<"你操作有误,请重试!"<<endl; }while (select!='1' && select!='2'); if(select=='2') return 0;// 退出 system("cls"); } return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值