进程与线程(五)用内核对象进行线程同步(上)
2012-05-10 14:59
337 查看
当系统初始化一个内核对象时,会将其结构内部的一个变量初始化为FALSE,也就是未触发状态。线程可以等待一个内核对象,进入等待状态,当这个内核对象变为TURE的触发状态时,唤醒线程。
线程内核对象在线程初始化时设置为未触发,当线程结束时设置为触发,所以我们可以用WaitForSingleObject来等待一个线程的结束,CreateEvent可以创建一个事件内核对象,可以用来进行同步。
线程内核对象在线程初始化时设置为未触发,当线程结束时设置为触发,所以我们可以用WaitForSingleObject来等待一个线程的结束,CreateEvent可以创建一个事件内核对象,可以用来进行同步。
1 int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) 2 { 3 _tsetlocale(LC_ALL,_T("chs") ); 4 system("title ReturnsMe的win32api测试程序"); 5 //创建一个事件内核对象 6 g_hevent = CreateEvent(NULL,FALSE,FALSE,_T("event")); 7 8 chBEGINTHREADEX(NULL,NULL,PrintThread,NULL,0,NULL); 9 HANDLE h = chBEGINTHREADEX(NULL,NULL,SetThread,NULL,0,NULL); 10 11 WaitForSingleObject(h,INFINITE); 12 13 system("pause"); 14 return 0; 15 } 16 DWORD WINAPI SetThread(PVOID pvParam) 17 { 18 for (int i =0;i<=100;i++) 19 { 20 g_num = g_num +i; 21 } 22 wprintf(_T("SetThread:g_num is %d \n"),g_num); 23 Sleep(2000); 24 SetEvent(g_hevent); //设置内核对象为触发状态 25 return 0; 26 } 27 28 DWORD WINAPI PrintThread(PVOID pvParam) 29 { 30 WaitForSingleObject(g_hevent,INFINITE); 31 wprintf(_T("PrintThread:g_num is %d \n"),g_num); 32 return 0; 33 } 除了事件内核对象以外,还有计时器,信号量,互斥量等等内核对象可以用来线程同步,未完待续.... update: 计时器允许我们在特定时间触发一个内核对象,并且可以每隔一段时间触发一次。下面是一个例子,注释很详细。 1 HANDLE g_htimer; 2 3 int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) 4 { 5 _tsetlocale(LC_ALL,_T("chs") ); 6 system("title ReturnsMe的win32api测试程序"); 7 8 //设置一个手动重置的内核对象,如果我们没有从外部调用这个计时器的需求,我们可以给名字传一个NULL 9 g_htimer = CreateWaitableTimer(NULL,FALSE,NULL); 10 11 FILETIME ftLocal,ftUTC,ftNewUTC; 12 SYSTEMTIME st; 13 14 //得到当前UTC时间,FILETIME格式 15 ftUTC = CFileTime::GetCurrentTime(); 16 //时区换算 17 FileTimeToLocalFileTime(&ftUTC,&ftLocal); 18 //转换成系统时间 19 FileTimeToSystemTime(&ftLocal,&st); 20 21 wprintf(_T("time is %d:%d:%d \n" ),st.wHour,st.wMinute,st.wSecond); 22 23 //即时时间加两秒,然后转换成FILETIME格式的UTC时间 24 st.wSecond = st.wSecond +2; 25 26 SystemTimeToFileTime(&st,&ftLocal); 27 LocalFileTimeToFileTime(&ftLocal,&ftNewUTC); 28 29 //这么做是为了兼容x64cpu,对齐地址 30 LARGE_INTEGER li; 31 li.HighPart = ftNewUTC.dwHighDateTime; 32 li.LowPart = ftNewUTC.dwLowDateTime; 33 34 //设置计时器,第二个参数传入绝对时间,也就是刚才得到的CFileTime::GetCurrentTime();的2s后 35 //第一次设置计时器为触发状态,以后每5s触发一次 36 SetWaitableTimer(g_htimer,&li,5000,NULL,NULL,FALSE); 37 HANDLE h = chBEGINTHREADEX(NULL,NULL,PrintThread,NULL,0,NULL); 38 39 WaitForSingleObject(h,1000*60); 40 41 system("pause"); 42 return 0; 43 } 44 DWORD WINAPI PrintThread(PVOID pvParam) 45 { 46 47 for (int i=0;i<=5;i++) 48 { 49 //循环等待,打印6次后退出线程 50 WaitForSingleObject(g_htimer,INFINITE); 51 wprintf(_T("this is the %dth time to call wprintf \n"),i+1); 52 } 53 54 //用完了就做掉它,=。=||| 55 CancelWaitableTimer(g_htimer); 56 57 return 0; 58 } 59 当然set函数也可以设置一个相对时间,而且也允许插入一个时间的apc HANDLE g_htimer; int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { _tsetlocale(LC_ALL,_T("chs") ); system("title ReturnsMe的win32api测试程序"); AccessTimerAndAPC(); system("pause"); return 0; } VOID AccessTimerAndAPC() { g_htimer = CreateWaitableTimer(NULL,TRUE,NULL); FILETIME ftUTC,ftLocal; SYSTEMTIME st; ftUTC = CFileTime::GetCurrentTime(); FileTimeToLocalFileTime(&ftUTC,&ftLocal); FileTimeToSystemTime(&ftLocal,&st); //上次是绝对时间,这次用相对时间,传给apc一个创建时间 LARGE_INTEGER li={0}; SetWaitableTimer(g_htimer,&li,1000,APCRoutine,(LPVOID)&st,FALSE); //当且仅当函数处于一个alertable state时,系统才会把计时器的APC函数添加到列队之中 SleepEx(INFINITE,TRUE); } VOID WINAPI APCRoutine(LPVOID lpArgToCompletionRoutine,DWORD dwTimerLowValue,DWORD dwTimerHighValue) { PSYSTEMTIME pst = (PSYSTEMTIME)lpArgToCompletionRoutine; wprintf(_T("apc is inserted to the routine at %d:%d:%d \n"),pst->wHour,pst->wMinute,pst->wSecond); Sleep(2000); FILETIME ftUTC,ftLocal; ftUTC = CFileTime::GetCurrentTime(); FileTimeToLocalFileTime(&ftUTC,&ftLocal); FileTimeToSystemTime(&ftLocal,pst); wprintf(_T("it's %d:%d:%d now \n"),pst->wHour,pst->wMinute,pst->wSecond); }
相关文章推荐
- 进程与线程(六)用内核对象进行线程同步(下)
- C++实现线程同步的几种方式 线程同步是指同一进程中的多个线程互相协调工作从而达到一致性。之所以需要线程同步,是因为多个线程同时对一个数据对象进行修改操作时,可能会对数据造成破坏,下面是多
- windows核心编程---用内核对象进行线程同步
- 《windows核心编程学习笔记》——使用互斥量变量内核对象进行线程同步
- 《Windows核心编程系列》八谈谈用内核对象进行线程同步
- 第九章:用内核对象进行线程同步(二) .
- Linux 线程信号量,进程信号量和内核驱动程序信号量(线程同步信号量,进程同步信号量和设备驱动同步信号量)
- Windows核心编程--用内核对象进行线程同步(一)
- 第9章 用内核对象进行线程同步(4)_死锁(DeadLock)及其他
- 摘自windows核心编程之用内核对象进行线程同步
- 第9章 用内核对象进行线程同步(1)_事件对象(Event)
- Windows核心编程(八)用内核对象进行线程同步
- Windows核心编程:用内核对象进行线程同步
- (CloseHandle函数)内核对象、进程和线程
- Windows核心编程学习九:利用内核对象进行线程同步
- 第9章 用内核对象进行线程同步(2)_可等待计时器(WaitableTimer)
- 【Windows】线程漫谈——线程同步之计时器内核对象
- (摘自windows核心编程之用内核对象进行线程同步)
- 《Windows核心编程 5th》读书笔记----第9章 用内核对象进行线程同步