?? c++.txt
字號:
#include <stdlib.h>
#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;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -