<<windows核心编程>>读书笔记---第9章 内核对象进行线程同步
2013-08-28 16:37
375 查看
这是比较重要的一章,经常使用。应该牢靠掌握。
等待函数:
这个函数经常使用啦,当hHandle变为已触发状态的时候返回,不然就进入等待状态。
这里我们需要注意的是返回值,分为三种:WAIT_OBJECT_0(线程等待的对象被触发),WAIT_TIMEOUT(等待超时),WAIT_FAILED(参数传入了无效的句柄等)
当然如果是等待多个对象:
参数都是显而易见的,第一个参数为内核对象的数量,第二个参数是内核对象数组,第三个参数指定是否为全部,第四个是等待时间。
第三个参数如果为TRUE,则表示所有的内核对象都被触发了,函数才返回。反之,有一个被触发就返回。
这里的返回值需要特殊强调一下:如果bWaitAll为True,返回值为WAIT_OBJECT_0,则表示所有对象都被触发了。如果,bWaitAll为False,且返回值为WAIT_OBJECT_0和WAIT_OBJECT_0+nCount-1之间的某个值,则表示数组中第几个对象触发了。
信号量内核对象:
创建:
第一个参数和最后一个参数依然是内核对象经常看到的结构,第二个参数是当前可使用的资源数,第三个参数是可使用资源的总量(最大量)。
其实用法还是很简单的,有时候我总是把它想的复杂,其实完全没必要。
声明一个信号量内核对象,在线程函数里,使用WaitForSingleObject()来等待信号量,如果当前的可使用资源数小于可使用资源的总量,那么等待函数就可以返回,从而执行后续步骤。当然,返回返回必然会导致可使用资源数的减少,调用ReleaseSemaphore来设置使用的资源数。当然这只是最基本的用法。
最后一个参数代表的是会返回当前资源的原始值,如果我们将lReleaseCount传入0或者一个极大值,lpPreviousCount也会返回0。
网摘了一段代码,还是挺清晰的:
互斥量内核对象:
互斥量其实和关键段差不多:
看这个表格,够言简意赅的。
互斥量和其他内核对象有点区别:如果线程请求其他内核对象,请求不到资源的话,会进入等待状态。但是,如果是线程请求互斥量,则先要检查互斥量锁归属的线程,如果是同一个线程,则将互斥量归属的线程计数+1,当然,如果不是同一个线程,则继续进入等待状态。
遗弃问题:
如果某个线程获得了互斥量,但是没有释放就线程结束了,系统会自动将互斥量的线程ID设置为0,并将其递归计数设置为0,然后系统会检查其他等待中的线程,公平的选择其中一个,将其变为可调度状态。注意WaitForSingleObject函数的返回值也会变为WAIT_ABANDONED。
等待函数:
DWORD WINAPI WaitForSingleObject( __in HANDLE hHandle, __in DWORD dwMilliseconds );
这个函数经常使用啦,当hHandle变为已触发状态的时候返回,不然就进入等待状态。
这里我们需要注意的是返回值,分为三种:WAIT_OBJECT_0(线程等待的对象被触发),WAIT_TIMEOUT(等待超时),WAIT_FAILED(参数传入了无效的句柄等)
当然如果是等待多个对象:
DWORD WINAPI WaitForMultipleObjects( __in DWORD nCount, __in const HANDLE* lpHandles, __in BOOL bWaitAll, __in DWORD dwMilliseconds );
参数都是显而易见的,第一个参数为内核对象的数量,第二个参数是内核对象数组,第三个参数指定是否为全部,第四个是等待时间。
第三个参数如果为TRUE,则表示所有的内核对象都被触发了,函数才返回。反之,有一个被触发就返回。
这里的返回值需要特殊强调一下:如果bWaitAll为True,返回值为WAIT_OBJECT_0,则表示所有对象都被触发了。如果,bWaitAll为False,且返回值为WAIT_OBJECT_0和WAIT_OBJECT_0+nCount-1之间的某个值,则表示数组中第几个对象触发了。
信号量内核对象:
创建:
HANDLE WINAPI CreateSemaphore( __in LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, __in LONG lInitialCount, __in LONG lMaximumCount, __in LPCTSTR lpName );
第一个参数和最后一个参数依然是内核对象经常看到的结构,第二个参数是当前可使用的资源数,第三个参数是可使用资源的总量(最大量)。
其实用法还是很简单的,有时候我总是把它想的复杂,其实完全没必要。
声明一个信号量内核对象,在线程函数里,使用WaitForSingleObject()来等待信号量,如果当前的可使用资源数小于可使用资源的总量,那么等待函数就可以返回,从而执行后续步骤。当然,返回返回必然会导致可使用资源数的减少,调用ReleaseSemaphore来设置使用的资源数。当然这只是最基本的用法。
BOOL WINAPI ReleaseSemaphore( __in HANDLE hSemaphore, __in LONG lReleaseCount, __out LPLONG lpPreviousCount );
最后一个参数代表的是会返回当前资源的原始值,如果我们将lReleaseCount传入0或者一个极大值,lpPreviousCount也会返回0。
网摘了一段代码,还是挺清晰的:
#include <windows.h> #include <iostream> #include <ctime> #include <fstream> using namespace std; HANDLE hSemaphore; struct ThreadInfo { int iID; LONG iCount; ThreadInfo* pThreadInfo; int iSleep; }; DWORD WINAPI ThreadProc(LPVOID lp) { ThreadInfo* pThreadInfo = (ThreadInfo*)lp; WaitForSingleObject(hSemaphore,INFINITE); Sleep(pThreadInfo->iSleep); cout << "线程" << pThreadInfo->iID << ":睡眠" << pThreadInfo->iSleep << endl; ReleaseSemaphore(hSemaphore,1,&(pThreadInfo->iCount)); cout << "线程" << pThreadInfo->iID << ":当前信号量资源数:" << pThreadInfo->iCount << " 信号量资源数加1" << endl; delete pThreadInfo->pThreadInfo; return 0; } int main(int argc, char *argv[]) { cout << "信号量当前资源数:4,最大资源数:5" << endl; hSemaphore = CreateSemaphore(NULL,4,5,NULL); HANDLE hThread[8]; srand((unsigned)time(0)); for(int i = 0;i < 8;++i) { ThreadInfo* threadInfo = new ThreadInfo; threadInfo->pThreadInfo = threadInfo; threadInfo->iID = i; threadInfo->iCount = -1; threadInfo->iSleep = rand() % 1000; hThread[i] = CreateThread(NULL,0,ThreadProc,(LPVOID)threadInfo,0,NULL); } WaitForMultipleObjects(8,hThread,TRUE,INFINITE); for(int i = 0;i < 8;++i) CloseHandle(hThread[i]); CloseHandle(hSemaphore); return 0; }
互斥量内核对象:
互斥量其实和关键段差不多:
看这个表格,够言简意赅的。
互斥量和其他内核对象有点区别:如果线程请求其他内核对象,请求不到资源的话,会进入等待状态。但是,如果是线程请求互斥量,则先要检查互斥量锁归属的线程,如果是同一个线程,则将互斥量归属的线程计数+1,当然,如果不是同一个线程,则继续进入等待状态。
遗弃问题:
如果某个线程获得了互斥量,但是没有释放就线程结束了,系统会自动将互斥量的线程ID设置为0,并将其递归计数设置为0,然后系统会检查其他等待中的线程,公平的选择其中一个,将其变为可调度状态。注意WaitForSingleObject函数的返回值也会变为WAIT_ABANDONED。
相关文章推荐
- <<Windows核心编程(第五版)>>第九章用内核对象进行线程同步:9.3事件内核对象
- <<windows核心编程>>读书笔记---第8章 用户模式下的线程同步
- 《Windows核心编程 5th》读书笔记----第9章 用内核对象进行线程同步
- Windows核心编程<读书笔记九>线程与内核对象的同步
- 第9章 用内核对象进行线程同步(3)_信号量(semaphore)、互斥对象(mutex)
- 第9章 用内核对象进行线程同步(4)_死锁(DeadLock)及其他
- 第9章 用内核对象进行线程同步(2)_可等待计时器(WaitableTimer)
- <<Linux内核的设计与实现>>读书笔记(三)-Linux的进程
- 第9章 用内核对象进行线程同步(1)_事件对象(Event)
- <<windows核心编程>>读书笔记---第6章 线程基础
- windows核心编程<读书笔记三>内核对象
- <<windows核心编程>>读书笔记---第4章 进程
- <<Effective OC>>读书笔记 --- 第八条 理解“对象等同”这一概念
- <<读书笔记>>系列--《理解专业程序员》tips
- 《Windows核心编程》读书笔记(六) 第9章 线程与内核对象的同步
- <<redis设计和实现>>读书笔记
- <<C++代码设计与重用>>读书笔记(一) Nice 类
- 用内核对象进行线程同步
- Windows-核心编程-09-如何用内核对象进行线程同步-信号内核对象
- <<测试驱动开发的艺术>>读书笔记