您的位置:首页 > 其它

读者——写者问题

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: