读者——写者问题

原创 2003年09月26日 22:55:00

#include <stdlib.h><?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]: %s/n", nReader, info);

    else

        sprintf(s_out, "/tWriter [%d]: %s/n", -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<RN; i++)

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

 

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

    for (int j=0; j<WN; 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] in/n”, g_cntReader, i);

        g_cntReader ++;

       // 如果是第一个读者

       if (g_cntReader == 1)

       {

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

           // 锁定文档

           P(Sdoc);

           printf("#----------[%d] <== Doc busy/n", 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 free/n", i);

           // 解锁文档

           V(Sdoc);

       }

        printf("//: %d Readers Left, [%d] is out/n”, 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 busy/n", -j);

 

       // ing……

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

 

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

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

 

       // 解锁文档

        V(Sdoc);

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

    }

 

    return 0;

}

 

读者-写者问题

读者写者是一个非常著名的同步问题。读者写者问题描述非常简单,有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者在读文件时写者也不去能写文件。用图来表示的话 ...
  • SpadgerZ
  • SpadgerZ
  • 2016年11月05日 15:36
  • 5353

读者写者问题(读者优先、写者优先、公平竞争)

读者优先: 1.写者、读者互斥访问文件资源。 2.多个读者可以同时访问文件资源。 3.只允许一个写者访问文件资源。 具体实现: 1.设置信号量fileSrc实现读写者对临界资源的访问。 2.设置计数...
  • c1194758555
  • c1194758555
  • 2016年10月13日 13:00
  • 2743

读者-写者问题

 读者与写者问题: (一)定义: 多个读者进程,与多个写者进程共享一个临界资源; (二)分析: 1.多个读者可以同时读; 2.多个写者不可以同时写; 3.读者和写者不可以同时进行; ...
  • legend050709
  • legend050709
  • 2014年09月03日 20:55
  • 1109

读者写者问题浅析(代码实现)

读者作家(RW)或共享独占锁(也称为多个读取器/单写入器锁定或多读卡器锁)的一个同步原语,解决了一个读者-writers问题。一个RW锁允许并发的只读操作的访问,而写操作需要独占访问。这意味着多个线程...
  • github_35124642
  • github_35124642
  • 2016年07月20日 20:41
  • 2048

经典同步问题(三)---读者写者问题

读者写者问题的信号量和条件变量算法
  • sunny_ss12
  • sunny_ss12
  • 2015年08月12日 03:06
  • 2508

操作系统PV操作及读者写者问题

1、信号量: 2、P、V操作原语可描述为以下式子: 3、解释: 4、互斥模式原理: 5、同步模式原理: 6、读者写者问题:...
  • Remoa_Dengqinyi
  • Remoa_Dengqinyi
  • 2016年09月22日 15:59
  • 4445

读者-写者问题(Reader-Writer Problem)

一、读者---写者问题(Reader-Writer Problem)      允许多个进程同时读一个共享对象,因为读操作不会使数据文件混乱。但不允许一个Writer进程和其他Reader进程或Wri...
  • ValDC_Morning
  • ValDC_Morning
  • 2017年06月18日 17:28
  • 831

读者-写者问题思想

读者-写者问题是一个经典的并发程序设计问题,是经常出现的一种同步问题。计算机系统中的数据(文件、记录)常被多个进程共享,但其中某些进程可能只要求读数据(称为读者);另一些进程则要求修改数据(称为写者)...
  • metheir
  • metheir
  • 2016年10月19日 22:11
  • 638

Java并发之读者写者模型

问题描述:设想一个飞机订票系统,其中有许多竞争的进程试图读写其中的数据。多个进程同时读取是可以接受的,但如果一个进程正在更新数据库,则所有的其他进程都不能访问数据库。即便是读操作也不行。Semapho...
  • c275046758
  • c275046758
  • 2016年01月24日 21:01
  • 1146

读者写者问题——读者优先,写者优先,公平竞争 解决方法

转自http://blog.csdn.net/yanfeivip8/article/details/12527047 本篇主要是从读者写者问题中的读者优先、写者优先、以及两者公平竞争三个方面解析...
  • JY_Sharer
  • JY_Sharer
  • 2013年11月26日 10:22
  • 4046
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:读者——写者问题
举报原因:
原因补充:

(最多只允许输入30个字)