多线程编程(16)

想过没有? WaitableTimer 是在 "定时等待", 前面例子中的 WaitForSingleObject 等待函数 "也在等待", 这就 "双重等待" 了, 这不好, 太浪费资源.

其实作为同步工具, 前面的几种方法(事件、信号、临界区)基本够用了; WaitableTimer 的作用并不是为了重复前面的功能, 它的主要功用类似 TTimer 类; 譬如每隔多长时间执行一段代码、或在指定的时间去执行一段代码.

既然有了方便的 TTimer, 何必再使用 WaitableTimer 呢?

因为 WaitableTimer 比 TTimer 精确的多, 它的间隔时间可以精确到毫秒、它的指定时间甚至是精确到 0.1 毫秒;

而 TTimer 驱动的 WM_TIMER 消息, 是消息队列中优先级最低的, 也就是再同一时刻 WM_TIMER 消息总是被最后处理.

还有重要的一点 WaitableTimer 可以跨线程、跨进程使用.

继续探讨一个重要的点: 很多时候为了让线程不冲突, 线程也在等待, 既然有等待, 那 WaitableTimer 非常精确的定时又有什么价值呢? 对这个问题的思考, 可以让我们很好地理解 APC 函数.

SetWaitableTimer 有个回调函数(其实是个过程), Windows 要求它的格式是:

procedure TimerAPCProc(
 lpArgToCompletionRoutine: Pointer;
 dwTimerLowValue: DWORD;
 dwTimerHighValue: DWORD
); stdcall;

函数名中有 APC 的字样, 指示这是个 APC 函数(尽管这个名称无所谓, 这是官方命名), 那什么是 APC 函数?

APC(Asyncroneus Procedure Call): 异步过程调用.

原来每个线程除了有单独的消息队列, 还有一个 APC 队列(等待执行的 APC 函数); 如果线程发现 APC 队列中有情况, 马上会跳过去执行, 执行完毕后才回来接着处理消息队列.

说起来麻烦, 使用的时候只按上面格式传入函数指针就行; 不过能进入 APC 队列的回调函数和其他回调函数还有一个很大的不同:

SetWaitableTimer 按格式调用 APC 函数后, 需要在 "当前线程" 见到一个 "等待", 此 APC 函数才可以进入队列.

这好像很费解, 例说一下: APC 队列有那么高的优先级, 因为对资源的优先使用会对其他消息有很大的影响, 肯定不能随便进入, 这是不是像生活中的贵宾席或贵宾通道?

也就是说, 要进入 APC 队列只有 SetWaitableTimer 的调用还不够, 还要通过 "等待函数" 介绍一下.

WaitForSingleObject 吗? 不是, 它不够级别; 下面是 Windows 认可的、可以介绍 APC 入列的等待函数:

SleepEx();
WaitForSingleObjectEx();
WaitForMultipleObjectsEx();
MsgWaitForMultipleObjectsEx();
SignalObjectAndWait();

时间: 2024-11-02 18:49:29

多线程编程(16)的相关文章

汇编教程之多线程编程

本课中,我们将学习如何进行多线程编程.另外我们还将学习如何在不同的线程间进行通信. 理论: 前一课中,我们学习了进程,其中讲到每一个进程至少要有一个主线程.这个线程其实是进程执行的一条线索,除此主线程外您还可以给进程增加其它的线程,也即增加其它的执行线索,由此在某种程度上可以看成是给一个应用程序增加了多任务功能.当程序运行后,您可以根据各种条件挂起或运行这些线程,尤其在多CPU的环境中,这些线程是并发运行的.这些是在W32下才有的概念,在WIN16下并没有等同的概念. 在同一进程中运行不同的线程

PHP多线程编程之管道通信实例分析

 这篇文章主要介绍了PHP多线程编程之管道通信,实例分析了管道通信的原理与相关使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下     本文实例讲述了PHP多线程编程之管道通信用法.分享给大家供大家参考.具体分析如下: 一个线程如果是个人英雄主义,那么多线程就是集体主义,你不再是一个独行侠,而是一个指挥家. 管道通信: 1. 管道可以认为是一个队列,不同的线程都可以往里面写东西,也都可以从里面读东西.写就是 在队列末尾添加,读就是在队头删除. 2. 管道一般有大小,默认一般是4K,也就是内容

Ruby多线程编程初步入门

  这篇文章主要介绍了Ruby多线程编程初步入门,线程是Ruby编程学习当中的重点和难点,需要的朋友可以参考下 传统程序有一个单独的线程执行,包含该程序的语句或指令顺序执行直到程序终止. 一个多线程的程序有多个线程的执行.在每个线程是按顺序执行的,但是在多核CPU机器上线程可能并行地执行.例如,通常情况下在单一CPU的机器,多个线程实际上不是并行执行的,而是模拟并行交叉的线程的执行. Ruby的可以使用 Thread 类很容易地编写多线程程序. Ruby线程是一个轻量级的和高效的在代码中实现并行

在Python下尝试多线程编程

  这篇文章主要介绍了在Python下多线程编程的尝试,由于GIL的存在,多线程在Python开发领域一直是个热门问题,需要的朋友可以参考下 多任务可以由多进程完成,也可以由一个进程内的多线程完成. 我们前面提到了进程是由若干线程组成的,一个进程至少有一个线程. 由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程. Python的标准库提供了两个模块:thread和thr

linux多线程编程详解教程

 这篇文章主要介绍了linux多线程编程详解教程,提供线程通过信号量实现通信的代码,大家参考使用吧 线程分类   线程按照其调度者可以分为用户级线程和核心级线程两种.   (1)用户级线程  用户级线程主要解决的是上下文切换的问题,它的调度算法和调度过程全部由用户自行选择决定,在运行时不需要特定的内核支持.在这里,操作系统往往会提供一个用户空间的线程库,该线程库提供了线程的创建.调度.撤销等功能,而内核仍然仅对进程进行管理.如果一个进程中的某一个线程调用了一个阻塞的系统调用,那么该进程包括该进程

关于linux c语言多线程编程的问题

问题描述 关于linux c语言多线程编程的问题 /* 以生产者和消费者模型问题来阐述Linux线程的控制和通信你 生产者线程将生产的产品送入缓冲区,消费者线程则从中取出产品. 缓冲区有N个,是一个环形的缓冲池. */#include #include #define BUFFER_SIZE 16 struct prodcons{ int buffer[BUFFER_SIZE];/*实际存放数据的数组*/ pthread_mutex_t lock;/*互斥体lock,用于对缓冲区的互斥操作*/

iOS多线程编程之三——GCD的应用

iOS多线程编程之三--GCD的应用 一.引言 在软件开发中使用多线程可以大大的提升用户体验度,增加工作效率.iOS系统中提供了多种分线程编程的方法,在前两篇博客都有提及: NSThread类进行多线程编程:http://my.oschina.net/u/2340880/blog/416524. NSOperation进行多线程操作编程:http://my.oschina.net/u/2340880/blog/416782. 上两个进行多线程编程的机制都是封装于Object-C的类与方法.这篇博

iOS多线程编程之二——NSOperation与NSOperationQueue

iOS多线程编程之二--NSOperation与NSOperationQueue 一.NSOperation解析 NSOperation是基于Object-C封装的一套管理与执行线程操作的类.这个类是一个抽象类,通常情况下,我们会使用NSInvocationOperation和NSBlockOperation这两个子类进行多线程的开发,当然我们也可以写继承于NSOperation的类,封装我们自己的操作类. 1.NSOperation抽象类中提供的逻辑方法 操作开始执行 ? 1 - (void)

关于多线程编程您不知道的 5 件事 有关高性能线程处理的微妙之处

虽然很少有 Java 开发人员能够忽视多线程编程和支持它的 Java 平台库,更少有人有时间深入研究线程.相反地,我们临时学习线程,在需要时向我们的工具箱添加新的技巧和技术.以这种方式构建和运行适当的应用程序是可行的,但是您可以做的不止这些.理解 Java 编译器的线程处理特性和 JVM 将有助于您编写更高效.性能更好的 Java 代码. 在这期的 5 件事 系列 中,我将通过同步方法.volatile 变量和原子类介绍多线程编程的一些更隐晦的方面.我的讨论特别关注于这些构建如何与 JVM 和