Reader and Writer问题(写者优先)

来源:互联网 发布:热血江湖怪物数据 2017 编辑:程序博客网 时间:2024/04/30 04:58
经典操作系统问题,代码中有注释,不懂的函数可以查阅msdn
//Reader and Writer 问题,写者优先,并发读,互斥写#include <Windows.h>#include <stdio.h>#include <process.h>#include <tchar.h>#include <time.h>#include <sys/timeb.h>#include <sys/types.h>volatile LONG cntR, cntW;//当前在读的reader数和当前所有的writer数目CRITICAL_SECTION csr, csw, db;//关键段,分别控制reader、writer和对数据库的访问CONDITION_VARIABLE cvr, cvw;//条件变量,用于SleepConditionVariableCS和WakeConditionVariable中,//用于控制对关键段的访问bool writing;int val;DWORD WINAPI ReaderThread(PVOID pvParam);//读者的线程DWORD WINAPI WriterThread(PVOID pvParam);//写者的线程void initRand();int main(int argc, char **argv){//初始化变量HANDLE flag;DWORD threadId;val = 0;writing = false;InitializeCriticalSection(&csw);InitializeCriticalSection(&csr);InitializeCriticalSection(&db);InitializeConditionVariable(&cvw);InitializeConditionVariable(&cvr);while (true){//循环不断产生reader和writersrand(time(NULL));int r = rand() % 6;if (r % 3 == 0){flag = CreateThread(NULL, 0, WriterThread, NULL, 0, &threadId);if (flag)printf("Writer thread %d created...\n", threadId);elseprintf("Error %d while creating Writer thread\n", GetLastError());CloseHandle(flag);}else{flag = CreateThread(NULL, 0, ReaderThread, NULL, 0, &threadId);if (flag)printf("Reader thread %d created...\n", threadId);elseprintf("Error %d while creating Reader thread\n", GetLastError());CloseHandle(flag);}Sleep(1000);}}DWORD WINAPI ReaderThread(PVOID pvParam){int threadId = GetCurrentThreadId();EnterCriticalSection(&csw);while (cntW > 0)SleepConditionVariableCS(&cvr, &csw, INFINITE);//确保写者优先。//如果当前有writer在等,则不让新生成的(还未开始读)reader继续进来LeaveCriticalSection(&csw);EnterCriticalSection(&csr);cntR++;printf("This is %d reading, val = %d\n", threadId, val);LeaveCriticalSection(&csr);//并发读Sleep(1500);EnterCriticalSection(&csr);cntR--;if (cntR == 0)WakeConditionVariable(&cvw);//没有reader了,唤醒writerprintf("Reader %d leaved, still %d reader(s) reading\n\n", threadId, cntR);LeaveCriticalSection(&csr);return 0;}DWORD WINAPI WriterThread(PVOID pvParam){int threadId = GetCurrentThreadId();EnterCriticalSection(&csw);cntW++;//写者优先LeaveCriticalSection(&csw);EnterCriticalSection(&csr);while (cntR > 0)SleepConditionVariableCS(&cvw, &csr, INFINITE);//如果当前还有reader在读,就等所有的reader读完再写LeaveCriticalSection(&csr);EnterCriticalSection(&db);//互斥写writing = true;initRand();val = rand();printf("this is %d writing, val = %d\n", threadId, val);Sleep(1500);LeaveCriticalSection(&db);EnterCriticalSection(&csw);cntW--;printf("Writer %d leaved, %d writer(s) waiting.\n\n", threadId, cntW);if (cntW == 0)WakeConditionVariable(&cvr);//没有writer了,唤醒readerLeaveCriticalSection(&csw);return 0;}void initRand(){// 如果支持高性能精度计数器,则使用其初始化随机种子(微秒级)LARGE_INTEGER nFrequency;if (::QueryPerformanceFrequency(&nFrequency)){LARGE_INTEGER nStartCounter;QueryPerformanceCounter(&nStartCounter);srand((unsigned)nStartCounter.LowPart);}else // 否则使用当前系统时间初始化随机种子(毫秒级){timeb stb;ftime(&stb);srand((unsigned)stb.millitm);}}


0 0
原创粉丝点击