第9章 用内核对象进行线程同步(2)_可等待计时器(WaitableTimer)

9.4 可等待的计时器内核对象——某个指定的时间或每隔一段时间触发一次

(1)创建可等待计时器:CreateWaitableTimer(使用时应把常量_WIN32_WINNT定义为0x0400


参数


描述


psa


安全属性(如使用计数、句柄继承等)


bManualReset


手动重置计时器还是自动重置计时器。

①当手动计时器被触发所有正在等待计时器的线程都变可为可调度。

②当自动计时器被触发时只有一个正在等待计数器的线程变为可调度


pszName


对象的名字

(2)也可以打开一个己经存在的可等待计时器:OpenWaitableTimer

(3)设置可等待计时器状态:SetWaitableTimer


参数


描述


HANDLE hTimer


要想触发的计时器


LARGE_INTEGER*  pDueTime


计时器第1次被触发的时间(应该为世界协调时UTC

说明:pDueTime为正数时是个绝对时间为负数时,表示一个相对时间,表示要在相对于调用该函数以后多少个(100ns)毫秒应第1次触发计时器。如5秒后,则应为

-5*10 000 000


LONG lPeriod


第一次触发后,每隔多少时触发一次(单位是微秒)。

如果希望计时器只触发一次,之后不再触后,该参数为0.


PTIMERAPCROUTINE pfnCR


要加入APC队列的回调函数


PVOID pvArgToCR


传给回调函数的额外参数


BOOL bResume


如果为TRUE,而且系统支持电源管理,那么在计时器触发的时候,系统会退出省电模式。如设为TRUE,但系统不支持省电模式,GetLastError就会返回ERROR_NOT_SUPPORTED 适用平台。一般设为FALSE

(4)取消计时器:CancelWaitableTimer,调用后计时器永远不会触发。

【SetWaitableTimer伪代码】——设置计时器在2015年8月18日14:00触发,以后每隔6小时触发一次

HANDLE hTimer;
SYSTEMTIME st = { 0 };
FILETIME ftLocal, ftUTC;
LARGE_INTEGER liUTC;

//创建一个自动的计时器对象
hTimer = CreateWaitableTimer(NULL, FALSE, NULL);

//首先,设置时间为2015年8月18日,14:00(本地时间)
st.wYear = 2015;
st.wMonth = 8;
st.wDay = 18;
st.wHour = 14;  //PM格式的
st.wMinute = 0;
st.wSecond = 0;
st.wMilliseconds = 0;

SystemTimeToFileTime(&st, &ftLocal);

//将本地时间转为UTC时间
LocalFileTimeToFileTime(&ftLocal, &ftUTC);

//将FILETIME转为LARGE_INTEGER(因为对齐方式不同)
//FILETIME结构的地址必须是4的整数倍(32位边界),
//而LARG_INTEGER结构的地址必须是8的整数倍(64位边界)
liUTC.LowPart = ftUTC.dwLowDateTime;
liUTC.HighPart = ftUTC.dwHighDateTime;

//设置计时器
//SetWaitableTimer传入的时间始终是UTC时间(这个时间必须是64位边界)
//在liUTC后,每隔6个小时触发一次
SetWaitableTimer(hTimer, &liUTC, 6 * 60 * 60 * 1000, NULL, NULL, FALSE);
时间: 2024-10-25 00:43:10

第9章 用内核对象进行线程同步(2)_可等待计时器(WaitableTimer)的相关文章

第9章 用内核对象进行线程同步(3)_信号量(semaphore)、互斥量(mutex)

9.5 信号量内核对象(Semaphore) (1)信号量的组成 ①计数器:该内核对象被使用的次数 ②最大资源数量:标识信号量可以控制的最大资源数量(带符号的32位) ③当前资源数量:标识当前可用资源的数量(带符号的32位) (2)信号量的使用规则 ①如果当前资源计数>0,那么信号量处于触发状态,表示有可用资源. ②如果当前资源计数=0,那么信号量处于未触发状态,表示没有可用资源. ③系统绝不会让当前资源计数变为负数: ④当前资源计数绝对不会大于最大资源计数 (3)信号量的用法 (4)相关函数

第9章 用内核对象进行线程同步(4)_死锁(DeadLock)及其他

9.7 线程同步对象速查表 对象 何时处于未触发状态 何时处于触发状态 成功等待的副作用 进程 进程仍在运行的时候 进程终止的时(ExitProcess.TerminateProcess) 没有 线程 线程仍在运行的时候 线程终止的时候(ExitThread.TermimateThread) 没有 作业 作业尚未超时的时候 作业超时的时候 没有 文件 有待处理的I/O请求的时候 I/O请求完成的时候 没有 控制台输入 没有输入的时候 有输入的时候 没有 文件变更通知 文件没有变更的时候 文件系统

线程同步——内核对象实现线程同步——信号量

1 /* 2 3 信号量内核对象 4 信号量与其它内核量相同,包含一个使用计数,除此之外还包含两个量. 5 一个最大资源计数和一个当前资源计数. 6 信号量规则如下: 7 如果当前资源计数大于0,那么信号量处于触发状态. 8 如果当前资源计数等于0,那么信号量处于未触发状态. 9 系统绝不会让当前资源计数变为负数. 10 当前资源计数绝不会大于最大资源计数. 11 12 下面我们看一下信号量的创建函数 13 HANDLE CreateSemaphore( 14 LPSECURITY_ATTRIB

线程同步——内核对象实现线程同步——事件内核对象

1 事件内核对象 2 3 事件类型对象有两种不同类型,手动重置和自动重置 4 手动重置:当一个手动重置对象被触发时候,等待该对象的所有线程变为可调度. 5 自动重置:当一个自动重置对象被触发时,只有一个等待该事件的线程会变为可调度 6 7 下面是一个创建事件内核对象的函数: 8 HANDLE CreateEvent( 9 LPSECURITY_ATTRIBUTES lpEventAttributes, 10 BOOL bManualReset, 11 BOOL bInitialState, 12

线程同步——内核对象实现线程同步——可等待计时器内核对象

1 可等待计时器 2 可等待计时器是这样一种内核对象,他们会在某个指定的时间触发或每隔一段时间触发一次. 5 下面我们来介绍一下创建可等待计时器函数: 6 7 HANDLE CreateWaitableTimer( 8 LPSECURITY_ATTRIBUTES lpTimerAttributes, 9 BOOL bManualReset, 10 LPCSTR lpTimerName ); 11 第一.三个参数我想我也不用介绍了哈,这是创建内核对象基本都会有的参数. 12 第二个参数bManua

线程同步——内核对象实现线程同步——等待函数

1 对于内核对象实现线程同步,不得不提三点: 2 1)大多数内核对象既有触发也有未触发两个状态 3 比如:进程.线程.作业.文件流.事件.可等待的计时器.信号量.互斥量 4 2)等待函数:等待函数使线程自愿进入等待状态,直到指定的内核对象变为触发状态为止, 5 说道等待我们最喜欢不过了,因为这样不会浪费我们宝贵的CPU时间. 6 3)对于自动重置对象来说,当对象被触发时,函数会自动检测到(手动重置对象为触发是,函数也能检测到), 7 并开始执行,但是在函数会在返回之前使事件变为非触发状态. 8

内核对象进行线程同步

前言: 具体的可等待的内核对象有: 进程,线程,作业,文件以及控制台的标准输入流/输出流/错误流,事件,可等待的计时器,信号量,互斥量. 等待函数: DWORD WaitForSingleObject( HANDLE hObject,//用来标识要等待的内核对象 DWORD dwMilliseconds);//等待的时间 DWORD WaitForMultipleObjects( DWORD dwCount,//函数检查的内核对象的数量(最大为MAXIMUM_WAIT_OBJECTS) CONS

Windows 互斥对象在线程同步上的运用

互斥对象在线程同步时的使用 1 多线程在资源共享的时候出现的问题 在程序中如果不同线程对同一个对象进行操作的话就有可能出现因为线程切换而导致的问题.例如下面的程序 #include <stdio.h> #include <WinSock2.h> #include <iostream> using namespace std; #pragma comment(lib,"ws2_32.lib") DWORD WINAPIfun1Proc(LPVOID l

第8章 用户模式下的线程同步(4)_条件变量(Condition Variable)

8.6 条件变量(Condition Variables)——可利用临界区或SRWLock锁来实现 8.6.1 条件变量的使用 (1)条件变量机制就是为了简化 “生产者-消费者”问题而设计的一种线程同步机制.其目的让线程以原子方式释放锁并将自己阻塞,直到某一个条件成立为止.如读者线程当没有数据可读取时,则应释放锁并等待,直到写者线程产生了新的数据.同理,当写者把数据结构写满时,那么写者应该释放SRWLock并等待,直到读者把数据结构清空. (2)等待函数:SleepConditionVariab