1:以异步方式调用函数
2:每隔一段时间调用一个函数
3:在内核对象触发时调用一个函数
4:在异步I/O请求完成时调用一个函数
第一个方式,显然就是普通的"线程池"都能做到的事情。用QueueUserWorkItem函数替代CreateThread来创建一个新的线程(例如socket监听返回一个客户端的连接)。
第二个方式,是计时器的作用。Windows GUI的计时器是和HWND绑定的,一次声明一个计时器,计时器结束的时候需要重新设定,用起来麻烦,而且是和消息队列绑定,无法用于复杂的后台服务。Windows线程池则解决了这个问题。
第三个方式,类似于Overlapped IO和线程同步编程。当然,线程同步的一堆复杂问题,已经由线程池为我们解决了,不再需要头疼了。
第四个方式,类似于AIO(APC),我们不再需要为每个I/O操作去指定Completion的回调操作,而是将这个回调注册给线程池统一管理。
第一个方式不用再举例,第四个方式要放在IOCP里面阐述。本文只讨论二,三两种方式。
第二个方式显然可以用于某种时间触发----下面这个例子声明了两个定时器,一个1s,一个2.5s。和直接用Sleep有什么不同呢? Sleep不管之前之后消耗了多少时间,都Sleep一个固定的区间,而Timer则是在精确的时间点唤醒回调函数,不受系统负载和程序cpu占用情况的影响。
|
开始计时
计时器1: 1s 1
计时器1: 1s 2
计时器2: 2.5s 3
计时器1: 1s 4
计时器1: 1s 5
计时器2: 2.5s 6
计时器1: 1s 7
计时器1: 1s 8
计时器1: 1s 9
计时器2: 2.5s 10
计时器1: 1s 11
计时器1: 1s 12
计时器1: 1s 13
计时器2: 2.5s 14
计时器1: 1s 15
计时器1: 1s 16
计时器2: 2.5s 17
计时器1: 1s 18
计时器1: 1s 19
计时器1: 1s 20
计时器2: 2.5s 21
Press any key to continue . . .
第三种情况,可以在上面的程序基础上改,把SetEvent的事件对象计数器,放到线程池里面去,让RegisterWaitForSingleObject来处理:
|
开始计时
计时器1: 1s 1
计时器1: 1s 2
计时器1: 1s 3
计时器1: 1s 4
Press any key to continue . . .
Windows编程 什么是作业
Windows编程 一个最简单的打印程序
Unix和Windows高级编程: 共享IO/异步IO
Windows编程 线程池的具体作用
Windows编程 AIO,APC,IOCP