读者——写者问题
2003-09-26 22:55
549 查看
#include[/b] <stdlib.h>
#include[/b] <windows.h>
#include[/b] "Reader-Writer.h"
#include[/b] "Semaphore.h"
// [/i]这是[/i] Windows [/i]下多线程工作的[/i] P [/i]操作[/i]
#define[/b] P(S) WaitForSingleObject(S, INFINITE[/b])
// [/i]这是[/i] Windows [/i]下多线程工作的[/i] V [/i]操作[/i]
#define[/b] V(S) ReleaseSemaphore(S, 1, NULL[/b])
const[/b] int[/b] RN = 5; // [/i]所有读者总数[/i]
const[/b] int[/b] WN = 3; // [/i]所有写者总数[/i]
HANDLE[/b] Sdoc; // [/i]文档信号量——互斥量[/i]
HANDLE[/b] Sr; // [/i]读者信号量——广义信号量[/i]
HANDLE[/b] Scnt; // [/i]保护[/i] g_cntReader [/i]的互斥量[/i]
int[/b] g_cntReader = 0; // [/i]读者个数计数器[/i]
// ##############+. Descripted By Tang Houjian [2003-9-26 20:10:49] .+##########[/i]
// | funcname : JustWait ( ) [/i]
// + note : [/i]显示一些信息,让后等待[/i]
// | [/i]
// +-----------------------------------------------------------------+
// | ret val : void
// | [/i]
// + Parameter : [/i]
// | [ int ] - nReader [/i]读者(写者)编号,读者[/i]>0[/i],写者[/i]<0[/i]
// | [ int ] - min [/i]操作等待的最短时间[/i]
// | [ int ] - max [/i]操作等待得最长时间,实际等待的时间介于两者之间[/i]
// | [ LPCSTR ] - info [/i]要显示的信息[/i]
void[/b] JustWait(int[/b] nReader, int[/b] min, int[/b] max, LPCSTR[/b] info)
// +-----------------------------------------------------------------+[/i]
{
// [/i]等待时间的基本量,以毫秒表示[/i]
const[/b] int[/b] BASETIME = 1000;
// [/i]实际等待得时间[/i]
int[/b] wait_time = 0;
if[/b] (max==min) // [/i]判断是为了避免[/i] %0[/i]错误,注意取随机值[/i]
wait_time = min*BASETIME;
else[/b]
wait_time = rand()%(max*BASETIME-min*BASETIME) + min*BASETIME;
// [/i]最终显示的信息缓冲[/i]
char[/b] s_out[128];
// [/i]读者大于[/i]0[/i],写者小于[/i]0[/i]
if[/b] (nReader > 0)
sprintf(s_out, "Reader [%d]: %s/n", nReader, info);
else[/b]
sprintf(s_out, "/tWriter [%d]: %s/n", -nReader, info);
// [/i]打印[/i]
printf(s_out);
// [/i]然后等待[/i]
Sleep(wait_time);
}
// [/i]这是主函数[/i]
void[/b] TryReaderAndWriter()
{
// [/i]创建信号量[/i] [/i]这是初值[/i]--+ +----[/i]这是最大信号量值[/i]
// | |[/i]
Sdoc = CreateSemaphore(NULL[/b], 1, 1, "Document");
// [/i]一次最多允许[/i] 3 [/i]个读者读[/i]
Sr = CreateSemaphore(NULL[/b], 3, 3, "ReaderNumber");
// [/i]他也是一个互斥信号量,初值为[/i] 1[/i]
Scnt = CreateSemaphore(NULL[/b], 1, 1, "ReaderCounterProtect");
// [/i]线程句柄[/i]
HANDLE[/b] threads[RN+WN];
// [/i]创建读者线程,共有[/i] RN [/i]个读者[/i]
for[/b] (int[/b] i=0; i<RN; i++)
threads = CreateThread(0, 0, Reader, 0, 0, 0);
// 创建写者线程,共有[/i] WN [/i]个写者[/i]
for[/b] (int[/b] j=0; j<WN; j++)
threads[j+RN] = CreateThread(0, 0, Writer, 0, 0, 0);
WaitForMultipleObjects(RN+WN, threads, TRUE[/b], INFINITE[/b]);
}
// [/i]读者线程[/i]
DWORD[/b] WINAPI[/b] Reader(LPVOID lpPara)
{
// [/i]注意是静态变量,可以使每来一个读者增加一[/i]
static[/b] int[/b] reader_num = 1;
int[/b] i = reader_num ++;
while[/b] (1)
{
JustWait(i, 1, 2, "I want to Read");
// [/i]读者未满[/i]
P(Sr);
// [/i]锁定读者计数器[/i]
P(Scnt);
printf("//: %d Readers in, [%d] in/n”, g_cntReader, i);
g_cntReader ++;
// [/i]如果是第一个读者[/i]
if[/b] (g_cntReader == 1)
{
JustWait(i, 1, 2, "I am NUMBER-ONE!");
// [/i]锁定文档[/i]
P(Sdoc);
printf("#[/b]----------[%d] <== Doc busy/n", i);
JustWait(i, 1, 2, "I have get the document");
}
// [/i]解锁读者计数器[/i]
V(Scnt);
// [/i]读[/i]ing[/i]…………[/i]
JustWait(i, 2, 5, "I am reading...");
JustWait(i, 1, 2, "I want to get out");
// [/i]锁定读者计数器[/i]
P(Scnt);
g_cntReader --;
// [/i]如果是最后一个[/i]
if[/b] (g_cntReader == 0)
{
JustWait(i, 1, 2, "I am the LAST-ONE!");
printf("----------#[/b][%d] ==> Doc free/n", i);
// [/i]解锁文档[/i]
V(Sdoc);
}
printf("//: %d Readers Left, [%d] is out/n”, g_cntReader, i);
// [/i]解锁读者计数器[/i]
V(Scnt);
// [/i]离开[/i]
V(Sr);
JustWait(i, 5, 3, "Rest^^^^^^^^^^^^");
}
return[/b] 0;
}
DWORD[/b] WINAPI[/b] Writer(LPVOID lpPara)
{
// [/i]注意是静态变量,可以使每来一个写者减去一,注意初值是负值[/i]
static[/b] int[/b] g_cnt = -1;
int[/b] j = g_cnt --;
while[/b] (1)
{
JustWait(j, 2, 4, "I want write...");
// [/i]锁定文档[/i]
P(Sdoc);
printf("/t#[/b]==========[%d] <== Doc busy/n", -j);
// [/i]写[/i]ing[/i]……[/i]
JustWait(j, 4, 3, "WRITING......");
JustWait(j, 1, 2, "write over! Out");
printf("/t==========#[/b][%d] ==> Doc free/n", -j);
// [/i]解锁文档[/i]
V(Sdoc);
JustWait(j, 8, 4, "Rest~~~~~~~~~~~~~");
}
return[/b] 0;
}
#include[/b] <windows.h>
#include[/b] "Reader-Writer.h"
#include[/b] "Semaphore.h"
// [/i]这是[/i] Windows [/i]下多线程工作的[/i] P [/i]操作[/i]
#define[/b] P(S) WaitForSingleObject(S, INFINITE[/b])
// [/i]这是[/i] Windows [/i]下多线程工作的[/i] V [/i]操作[/i]
#define[/b] V(S) ReleaseSemaphore(S, 1, NULL[/b])
const[/b] int[/b] RN = 5; // [/i]所有读者总数[/i]
const[/b] int[/b] WN = 3; // [/i]所有写者总数[/i]
HANDLE[/b] Sdoc; // [/i]文档信号量——互斥量[/i]
HANDLE[/b] Sr; // [/i]读者信号量——广义信号量[/i]
HANDLE[/b] Scnt; // [/i]保护[/i] g_cntReader [/i]的互斥量[/i]
int[/b] g_cntReader = 0; // [/i]读者个数计数器[/i]
// ##############+. Descripted By Tang Houjian [2003-9-26 20:10:49] .+##########[/i]
// | funcname : JustWait ( ) [/i]
// + note : [/i]显示一些信息,让后等待[/i]
// | [/i]
// +-----------------------------------------------------------------+
// | ret val : void
// | [/i]
// + Parameter : [/i]
// | [ int ] - nReader [/i]读者(写者)编号,读者[/i]>0[/i],写者[/i]<0[/i]
// | [ int ] - min [/i]操作等待的最短时间[/i]
// | [ int ] - max [/i]操作等待得最长时间,实际等待的时间介于两者之间[/i]
// | [ LPCSTR ] - info [/i]要显示的信息[/i]
void[/b] JustWait(int[/b] nReader, int[/b] min, int[/b] max, LPCSTR[/b] info)
// +-----------------------------------------------------------------+[/i]
{
// [/i]等待时间的基本量,以毫秒表示[/i]
const[/b] int[/b] BASETIME = 1000;
// [/i]实际等待得时间[/i]
int[/b] wait_time = 0;
if[/b] (max==min) // [/i]判断是为了避免[/i] %0[/i]错误,注意取随机值[/i]
wait_time = min*BASETIME;
else[/b]
wait_time = rand()%(max*BASETIME-min*BASETIME) + min*BASETIME;
// [/i]最终显示的信息缓冲[/i]
char[/b] s_out[128];
// [/i]读者大于[/i]0[/i],写者小于[/i]0[/i]
if[/b] (nReader > 0)
sprintf(s_out, "Reader [%d]: %s/n", nReader, info);
else[/b]
sprintf(s_out, "/tWriter [%d]: %s/n", -nReader, info);
// [/i]打印[/i]
printf(s_out);
// [/i]然后等待[/i]
Sleep(wait_time);
}
// [/i]这是主函数[/i]
void[/b] TryReaderAndWriter()
{
// [/i]创建信号量[/i] [/i]这是初值[/i]--+ +----[/i]这是最大信号量值[/i]
// | |[/i]
Sdoc = CreateSemaphore(NULL[/b], 1, 1, "Document");
// [/i]一次最多允许[/i] 3 [/i]个读者读[/i]
Sr = CreateSemaphore(NULL[/b], 3, 3, "ReaderNumber");
// [/i]他也是一个互斥信号量,初值为[/i] 1[/i]
Scnt = CreateSemaphore(NULL[/b], 1, 1, "ReaderCounterProtect");
// [/i]线程句柄[/i]
HANDLE[/b] threads[RN+WN];
// [/i]创建读者线程,共有[/i] RN [/i]个读者[/i]
for[/b] (int[/b] i=0; i<RN; i++)
threads = CreateThread(0, 0, Reader, 0, 0, 0);
// 创建写者线程,共有[/i] WN [/i]个写者[/i]
for[/b] (int[/b] j=0; j<WN; j++)
threads[j+RN] = CreateThread(0, 0, Writer, 0, 0, 0);
WaitForMultipleObjects(RN+WN, threads, TRUE[/b], INFINITE[/b]);
}
// [/i]读者线程[/i]
DWORD[/b] WINAPI[/b] Reader(LPVOID lpPara)
{
// [/i]注意是静态变量,可以使每来一个读者增加一[/i]
static[/b] int[/b] reader_num = 1;
int[/b] i = reader_num ++;
while[/b] (1)
{
JustWait(i, 1, 2, "I want to Read");
// [/i]读者未满[/i]
P(Sr);
// [/i]锁定读者计数器[/i]
P(Scnt);
printf("//: %d Readers in, [%d] in/n”, g_cntReader, i);
g_cntReader ++;
// [/i]如果是第一个读者[/i]
if[/b] (g_cntReader == 1)
{
JustWait(i, 1, 2, "I am NUMBER-ONE!");
// [/i]锁定文档[/i]
P(Sdoc);
printf("#[/b]----------[%d] <== Doc busy/n", i);
JustWait(i, 1, 2, "I have get the document");
}
// [/i]解锁读者计数器[/i]
V(Scnt);
// [/i]读[/i]ing[/i]…………[/i]
JustWait(i, 2, 5, "I am reading...");
JustWait(i, 1, 2, "I want to get out");
// [/i]锁定读者计数器[/i]
P(Scnt);
g_cntReader --;
// [/i]如果是最后一个[/i]
if[/b] (g_cntReader == 0)
{
JustWait(i, 1, 2, "I am the LAST-ONE!");
printf("----------#[/b][%d] ==> Doc free/n", i);
// [/i]解锁文档[/i]
V(Sdoc);
}
printf("//: %d Readers Left, [%d] is out/n”, g_cntReader, i);
// [/i]解锁读者计数器[/i]
V(Scnt);
// [/i]离开[/i]
V(Sr);
JustWait(i, 5, 3, "Rest^^^^^^^^^^^^");
}
return[/b] 0;
}
DWORD[/b] WINAPI[/b] Writer(LPVOID lpPara)
{
// [/i]注意是静态变量,可以使每来一个写者减去一,注意初值是负值[/i]
static[/b] int[/b] g_cnt = -1;
int[/b] j = g_cnt --;
while[/b] (1)
{
JustWait(j, 2, 4, "I want write...");
// [/i]锁定文档[/i]
P(Sdoc);
printf("/t#[/b]==========[%d] <== Doc busy/n", -j);
// [/i]写[/i]ing[/i]……[/i]
JustWait(j, 4, 3, "WRITING......");
JustWait(j, 1, 2, "write over! Out");
printf("/t==========#[/b][%d] ==> Doc free/n", -j);
// [/i]解锁文档[/i]
V(Sdoc);
JustWait(j, 8, 4, "Rest~~~~~~~~~~~~~");
}
return[/b] 0;
}
相关文章推荐
- 秒杀多线程第十四篇 读者写者问题继 读写锁SRWLock
- wait, notify, notifyAll, 简单数组模拟队列实现读者写者问题。
- 秒杀多线程第十四篇 读者写者问题继 读写锁SRWLock
- 经典的IPC问题 -- 哲学家就餐问题、读者-写者问题、理发师睡觉问题、生产者-消费者问题详解
- OS: 读者写者问题(写者优先+LINUX+多线程+互斥量+代码)
- 操作系统——读者写者问题详解
- 秒杀多线程第十一篇 读者写者问题
- 互斥量和条件变量解决读者-写者问题
- (操作系统原理·第三章)读者-写者问题
- C# 多线程编程 经典模型 读者和写者问题
- Linux多线程实践(6) --Posix读写锁解决读者写者问题
- 读者写者问题
- linux中关于IPC(一部分涉及读者写者问题)
- OS: 读者写者问题(写者优先+LINUX+多线程+互斥量+代码)(转)
- 读者写者问题的C++实现(使用boost)
- 用信号量解决读者写者问题
- 信号量 读者写者问题
- 进程同步的经典问题1——读者写者问题(写者优先与公平竞争)
- 读者写者问题
- 读者写者问题