win32线程创建、线程同步以及读者写者问题
来源:互联网 发布:java checkboxgroup 编辑:程序博客网 时间:2024/05/17 01:58
include "stdafx.h" #include <stdio.h> #include <windows.h> #include <process.h>//设置控制台输出颜色 BOOL SetConsoleColor(WORD wAttributes) { HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); if (hConsole == INVALID_HANDLE_VALUE) return FALSE; return SetConsoleTextAttribute(hConsole, wAttributes); }//设置控制台输出蓝色字体void ConsolePrintBlue(char *pszFormat, ...) { va_list pArgList; va_start(pArgList, pszFormat); SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN);vfprintf(stdout, pszFormat, pArgList); SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); va_end(pArgList); }//线程函数unsigned int __stdcall Threadfun(LPVOID lpParam) { LPDWORD pData = (LPDWORD)lpParam;for(int i = 0;i < 10; i++) { Sleep(100); //子线程挂起100毫秒printf("Thread_ID = %d , \tParameters = %d, \ti = %d\n", GetCurrentThreadId(), *pData, i); } _endthreadex(0); return 0; } //如果在代码中有使用标准C运行库中的函数时,尽量使用_beginthreadex()来代替CreateThread()void ThreadexTest(){ConsolePrintBlue("--------- 进入线程创建、挂起、关闭测试 ---------\n");DWORD Para0, Para1; // 设置线程传递参数HANDLE hThread[2]; Para0 = 0; Para1 = 1; //创建线程0并挂起hThread[0] = (HANDLE)_beginthreadex(NULL, 0, Threadfun, &Para0, CREATE_SUSPENDED, NULL); hThread[1] = (HANDLE)_beginthreadex(NULL, 0, Threadfun, &Para1, 0, NULL); Sleep(110); //主线程挂起110毫秒,期间线程1正好可以输出一次ResumeThread(hThread[0]); //恢复线程0SuspendThread(hThread[1]); //挂起线程1Sleep(510); //主线程挂起510毫秒,期间线程0正好可以输出5次//终止线程0的运行TerminateThread(hThread[0], 0); //并不保证线程被终止,最好采用线程函数返回方式终止ResumeThread(hThread[1]); //恢复线程1WaitForSingleObject(hThread[1], INFINITE); //等待线程1执行完CloseHandle(hThread[0]);CloseHandle(hThread[1]);ConsolePrintBlue("--------- 结束线程创建、挂起、关闭测试 ---------\n\n\n");}CRITICAL_SECTION g_cs;//关键段线程函数unsigned int _stdcall CriticalSection(LPVOID lpParam){ EnterCriticalSection(&g_cs);//进入关键段printf("Thread_ID%d start\n", GetCurrentThreadId());ConsolePrintBlue("挂起线程100毫秒\n");Sleep(100); //挂起线程100毫秒printf("Thread_ID%d end\n\n", GetCurrentThreadId());LeaveCriticalSection(&g_cs);//离开关键段_endthreadex(0);return 0;}//关键段测试函数void CriticalSectionTest(){ConsolePrintBlue("\n--------- 使用临界区(CRITICAL_SECTION及其系列函数)实现线程同步 ---------\n");InitializeCriticalSection(&g_cs); //初始化g_cs的成员 HANDLE hThread[10]; for(int i = 0; i < 10; i++){ hThread[i] = (HANDLE)_beginthreadex(NULL, 0, CriticalSection, NULL, 0, NULL); }WaitForMultipleObjects(10, hThread, TRUE, INFINITE); for(int i = 0; i < 10; i++){CloseHandle(hThread[i]);} DeleteCriticalSection(&g_cs);//删除关键段ConsolePrintBlue("\\----- end ------\n\n\n");}RTL_SRWLOCK lock;//互斥锁线程函数unsigned int _stdcall SrwLock(LPVOID lpParam){ AcquireSRWLockExclusive(&lock); //进入读写锁printf("Thread_ID%d start\n", GetCurrentThreadId());ConsolePrintBlue("挂起线程100毫秒\n");Sleep(100); //挂起线程100毫秒printf("Thread_ID%d end\n\n", GetCurrentThreadId());ReleaseSRWLockExclusive(&lock); //结束读写锁_endthreadex(0);return 0;}//互斥锁测试函数void SrwLockTest(){ConsolePrintBlue("\n--------- 使用互斥锁(RTL_SRWLOCK及其系列函数)实现线程同步 ---------\n");HANDLE hThread[10]; InitializeSRWLock(&lock);//初始化lock的成员 for(int i = 0; i < 10; i++){ hThread[i] = (HANDLE)_beginthreadex(NULL, 0, SrwLock, NULL, 0, NULL); }WaitForMultipleObjects(10, hThread, TRUE, INFINITE); ConsolePrintBlue("\\----- end ------\n\n\n");}HANDLE semaphore;//信号量线程函数unsigned int _stdcall Semaphore(LPVOID lpParam){WaitForSingleObject(semaphore, INFINITE); //执行WaitForSingleObject一次,计数值就减一 printf("Thread_ID%d start\n", GetCurrentThreadId());ConsolePrintBlue("挂起线程100毫秒\n");Sleep(100);printf("Thread_ID%d end\n\n", GetCurrentThreadId());ReleaseSemaphore(semaphore, 1, NULL); //计数加一_endthreadex(0);return 0;}//信号量测试函数void SemaphoreTest(){ConsolePrintBlue("\n--------- 使用信号量内核对象实现线程同步 ---------\n");HANDLE hThread[10];semaphore = CreateSemaphore(NULL, 1, 1, NULL); //初始计数为1,最大计数为1for(int i = 0; i < 10; i++){ hThread[i] = (HANDLE)_beginthreadex(NULL, 0, Semaphore, NULL, 0, NULL); }WaitForMultipleObjects(10, hThread, TRUE, INFINITE); CloseHandle(semaphore);ConsolePrintBlue("\\----- end ------\n\n\n");}HANDLE hEvent; //事件线程函数unsigned int _stdcall Event(LPVOID lpParam){WaitForSingleObject(hEvent, INFINITE); //自动复位,变为无信号printf("Thread_ID%d start\n", GetCurrentThreadId());ConsolePrintBlue("挂起线程100毫秒\n");Sleep(100);printf("Thread_ID%d end\n\n", GetCurrentThreadId());SetEvent(hEvent); //设置为有信号_endthreadex(0);return 1;}//事件测试函数void EventTest(){ConsolePrintBlue("\n--------- 使用事件内核对象实现线程同步 ---------\n");HANDLE hThread[10];hEvent = CreateEvent(NULL, false, true, NULL); //初始bManualReset设置为false,bInitialState设置为有信号for(int i = 0; i < 10;i++){hThread[i] =(HANDLE)_beginthreadex(NULL, 0, Event , NULL, 0, NULL); }WaitForMultipleObjects(10, hThread, TRUE, INFINITE); CloseHandle(hEvent);ConsolePrintBlue("\\----- end ------\n\n\n");}const int QUEUE_LEN = 10; //环形队列长度int g_queue[QUEUE_LEN]; //环形队列int g_i, g_j; int nDataR, nDataW; HANDLE g_hEmpty, g_hFull; //读写信号量,读者在读信号量不为空则可读,写者在写信息量不为满则可写 HANDLE g_hEventReader, g_hEventWriter; //读者、写者事件,仅能一次一个写者进行写操作,一个读者进行读操作//读者线程输出函数void ReaderPrintRed(char *pszFormat, ...) { va_list pArgList; va_start(pArgList, pszFormat); EnterCriticalSection(&g_cs); SetConsoleColor(FOREGROUND_RED);vfprintf(stdout, pszFormat, pArgList); SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); LeaveCriticalSection(&g_cs); va_end(pArgList); } //写者线程输出函数 void WriterPrintGreen(char *pszStr, ...) { va_list pArgList; va_start(pArgList, pszStr); EnterCriticalSection(&g_cs); SetConsoleColor(FOREGROUND_GREEN); vfprintf(stdout, pszStr, pArgList); SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); LeaveCriticalSection(&g_cs); } //单个读者线程函数unsigned int __stdcall ReaderThreadFun(PVOID pM) { ReaderPrintRed("编号为%d的读者开始读取数据...\n", GetCurrentThreadId()); int nDataR = 0; while (nDataR < 20) { WaitForSingleObject(g_hFull, INFINITE); //等待数据队列不为空 nDataR = g_queue[g_i]; g_i = (g_i + 1)%QUEUE_LEN; ReaderPrintRed("编号为%d读者从队列中读取数据%d\n", GetCurrentThreadId(), nDataR); ReleaseSemaphore(g_hEmpty, 1, NULL); } ReaderPrintRed("编号为%d的读者结束读取数据//end\n", GetCurrentThreadId()); return 0; }//单个写者线程函数unsigned int __stdcall WriterThreadFun(PVOID pM) { WriterPrintGreen("编号为%d的写者开始写数据...\n", GetCurrentThreadId());int nDataR = 0; while (nDataR < 20) { WaitForSingleObject(g_hEmpty, INFINITE); //等待数据队列有空位g_queue[g_j] = ++nDataR; g_j = (g_j + 1)%QUEUE_LEN; WriterPrintGreen("编号为%d写者将数据%d写入队列\n", GetCurrentThreadId(), nDataR); ReleaseSemaphore(g_hFull, 1, NULL); //g_hFull信号量加一} WriterPrintGreen("编号为%d的写者结束写数据//end\n", GetCurrentThreadId()); return 0; } //多个读者线程函数unsigned int __stdcall MultiReaderThreadFun(PVOID pM){ReaderPrintRed("编号为%d的读者开始读取数据...\n", GetCurrentThreadId()); while (nDataR < 20) { WaitForSingleObject(g_hEventReader, INFINITE); //一次只能进入一个读者if (nDataR >= 20) {SetEvent(g_hEventReader);ReaderPrintRed("编号为%d的读者结束读数据..//end\n", GetCurrentThreadId()); return 0;}WaitForSingleObject(g_hFull, INFINITE);nDataR = g_queue[g_i]; g_i = (g_i + 1)%QUEUE_LEN; ReaderPrintRed("编号为%d读者从队列中读取数据%d\n", GetCurrentThreadId(), nDataR);ReleaseSemaphore(g_hEmpty, 1, NULL);SetEvent(g_hEventReader);} ReaderPrintRed("编号为%d的读者结束读取数据//end\n", GetCurrentThreadId()); return 0; }//多个写者线程函数unsigned int __stdcall MultiWriterThreadFun(PVOID pM){ WriterPrintGreen("编号为%d的写者开始写数据...\n", GetCurrentThreadId());while (nDataW < 20) { WaitForSingleObject(g_hEventWriter, INFINITE); //一次仅能进入一个读者if (nDataW >= 20){SetEvent(g_hEventWriter);WriterPrintGreen("编号为%d的写者结束写数据..//end\n", GetCurrentThreadId()); return 0;}WaitForSingleObject(g_hEmpty, INFINITE);g_queue[g_j] = ++nDataW; g_j = (g_j + 1) % QUEUE_LEN; WriterPrintGreen("编号为%d的写者将数据%d写入队列\n", GetCurrentThreadId(), nDataW); ReleaseSemaphore(g_hFull, 1, NULL); SetEvent(g_hEventWriter);} WriterPrintGreen("编号为%d的写者结束写数据//end\n", GetCurrentThreadId()); return 0; }//一个写者一个读者void SingleReaderSingleWirterTest(){ ConsolePrintBlue("\n----------- 模拟一个写者和一个读者之间访问环形队列操作 ---------\n");HANDLE hThread[2]; g_i = g_j = 0; nDataR = nDataW = 0;InitializeCriticalSection(&g_cs); //初始化g_cs的成员 g_hEmpty = CreateSemaphore(NULL, QUEUE_LEN, QUEUE_LEN, NULL); //初始信号量为满,最大信号量为环形队列总个数 g_hFull = CreateSemaphore(NULL, 0, QUEUE_LEN, NULL); //初始信号量为空,最大信号量为环形队列总个数 hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ReaderThreadFun, NULL, 0, NULL); hThread[1] = (HANDLE)_beginthreadex(NULL, 0, WriterThreadFun, NULL, 0, NULL); WaitForMultipleObjects(2, hThread, TRUE, INFINITE); for (int i = 0; i < 2; i++) {CloseHandle(hThread[i]); }CloseHandle(g_hEmpty); CloseHandle(g_hFull); ConsolePrintBlue("循环队列中保存的数为:\n");for (int i = 0; i < QUEUE_LEN; i++){printf("%-6d", g_queue[i]);}printf("\n");DeleteCriticalSection(&g_cs);//删除关键段ConsolePrintBlue("\\----- end ------\n\n\n");}//一个写者十个读者void MultiReaderSingleWirterTest(){ConsolePrintBlue("\n----------- 模拟一个写者和多个读者之间访问缓形队列操作 ---------\n");g_i = g_j = 0; HANDLE hThreadR[10];HANDLE hThreadW;nDataR = nDataW = 0;InitializeCriticalSection(&g_cs); g_hEmpty = CreateSemaphore(NULL, 1, QUEUE_LEN, NULL); g_hFull = CreateSemaphore(NULL, 0, QUEUE_LEN, NULL); g_hEventReader = CreateEvent(NULL, false, true, NULL); //设置事件,每次仅能一个读者读for (int i = 0; i < 10; i++){hThreadR[i] = (HANDLE)_beginthreadex(NULL, 0, MultiReaderThreadFun, NULL, 0, NULL); } hThreadW = (HANDLE)_beginthreadex(NULL, 0, WriterThreadFun, NULL, 0, NULL); WaitForSingleObject(hThreadW, INFINITE);WaitForMultipleObjects(10, hThreadR, TRUE, INFINITE); for (int i = 0; i < 10; i++) {CloseHandle(hThreadR[i]); }CloseHandle(hThreadW);CloseHandle(g_hEmpty); CloseHandle(g_hFull); ConsolePrintBlue("循环队列中保存的数为:\n");for (int i = 0; i < QUEUE_LEN; i++){printf("%-6d", g_queue[i]);}printf("\n");DeleteCriticalSection(&g_cs); ConsolePrintBlue("\\----- end ------\n\n\n");}//十个写者十个读者void MultiReaderMultiReaderWriterTest() {ConsolePrintBlue("\n----------- 模拟多个写者和多个读者之间访问环形队列操作 ---------\n");g_i = g_j = 0; HANDLE hThreadR[10];HANDLE hThreadW[10];nDataR = nDataW = 0;InitializeCriticalSection(&g_cs); g_hEventReader = CreateEvent(NULL, false, true, NULL); //设置事件,每次仅能一个读者读g_hEventWriter = CreateEvent(NULL, false, true, NULL); //设置事件,每次仅能一个写者写g_hEmpty = CreateSemaphore(NULL, 1, QUEUE_LEN, NULL); //初始计数为一,最大计数为十g_hFull = CreateSemaphore(NULL, 0, QUEUE_LEN, NULL); //初始计数为零,最大计数为十for (int i = 0; i < 10; i++){hThreadR[i] = (HANDLE)_beginthreadex(NULL, 0, MultiReaderThreadFun, NULL, 0, NULL); } for(int i = 0; i < 10; i++){hThreadW[i] = (HANDLE)_beginthreadex(NULL, 0, MultiWriterThreadFun, NULL, 0, NULL); }WaitForMultipleObjects(10, hThreadR, TRUE, INFINITE); WaitForMultipleObjects(10, hThreadW, TRUE, INFINITE);for (int i = 0; i < 10; i++) {CloseHandle(hThreadR[i]); CloseHandle(hThreadW[i]);}CloseHandle(g_hEmpty); CloseHandle(g_hFull); ConsolePrintBlue("循环队列中保存的数为:\n");for (int i = 0; i < QUEUE_LEN; i++){printf("%-6d", g_queue[i]);}printf("\n");DeleteCriticalSection(&g_cs); ConsolePrintBlue("\\----- end ------\n\n\n");}void main() { ConsolePrintBlue("----------- 基于win32平台下编写多线程操作 -----------\n\n");//创建线程,关闭线程,挂起线程ConsolePrintBlue("\n\n\n----------- 1:创建线程,关闭线程,挂起线程 -----------\n\n");ThreadexTest();//使用临界资源,互斥锁,信号量,事件ConsolePrintBlue("\n\n\n\n\n----------- 2:使用临界资源,互斥锁,信号量,事件 -----------\n\n");CriticalSectionTest(); SrwLockTest(); SemaphoreTest(); EventTest();//读者写者问题ConsolePrintBlue("\n\n\n\n\n----------- 3:读者写者问题 -----------\n\n"); SingleReaderSingleWirterTest(); MultiReaderSingleWirterTest();MultiReaderMultiReaderWriterTest();}
0 0
- win32线程创建、线程同步以及读者写者问题
- .NET_C#_线程_读者写者同步问题
- 读者写者 问题C线程实现 linux平台
- 线程之路六:读者写者的问题
- win32 pv操作 读者写者问题
- 读者与写者同步问题
- Win32线程同步
- Win32 - 线程同步
- 12.[个人]C++线程入门到进阶(12)----读者写者问题&读写锁SRWLock
- 读者-写者同步问题的写者优先实现
- 经典同步问题(三)---读者写者问题
- 经典同步问题--读者和写者问题
- 经典进程同步问题:读者-写者问题
- win32创建一个线程
- 线程、创建线程、终止线程、线程同步
- 读者写者问题
- 读者写者问题
- 读者-写者问题
- 假设指令:MOV BX
- unity 插件 iTween简单用法
- 由dct变换想到的
- LoadRunner 术语
- JNI字段描述符“([Ljava/lang/String;)V”
- win32线程创建、线程同步以及读者写者问题
- 使用pjsip开发
- hibernate优化
- python统计文本中单词个数
- 命名空间“Microsoft”中不存在类型或命名空间名称“Office ”(是缺少程序集引用吗?)
- Android常用mimeType表
- linux 下查看文件个数及大小
- 全新 Audi A8/A8 L 頂級豪華旗艦與九億遊艇攜手登場
- LeetCode之Pascal's Triangle II