【问题标题】:kernel timer objects and synchronization内核定时器对象和同步
【发布时间】:2012-11-06 16:26:57
【问题描述】:

我想知道是否有人可以简单地告诉我(我知道这不是一个简单的主题)如何使用内核计时器对象来同步对内核中数据结构的访问?

编辑:

内核定时器对象是内核调度器对象的一部分,它们是内核的同步对象组。我还想知道计时器对象是否是线程必须等待获得句柄才能继续的东西,或者是线程等待获得句柄的计时器到期时触发的回调?

我希望这是有道理的。内核对我来说是一个新主题。

【问题讨论】:

    标签: windows data-structures kernel timer


    【解决方案1】:

    简答:计时器对象用于同步对内核中数据结构的访问。为此,NT 内核具有诸如快速互斥锁、受保护互斥锁、推送锁、互斥对象等之类的东西。我不太明白你的问题——你在说什么数据结构?尽管如此,我将继续假设您想知道如何使用计时器对象。

    有两种方法可以使用计时器对象。第一个是在指定的到期时间之后发出信号。因此,线程可能会使用 KeWaitForSingleObject 等待计时器对象,并且它只会在到期时间到达后唤醒。您还可以为计时器使用周期性信号 - 您可能希望每次线程被它唤醒时将其重置为非信号状态,并每隔几秒收到信号。

    第二个(不太常见的)用途是计时器对象可以将 APC 插入到设置计时器的线程中。如果您不知道 APC 是什么 - 它是一个异步过程调用。如果线程执行alertable wait,插入的 APC 将中断等待并开始执行。当然 APC 使用起来很棘手,这就是为什么人们喜欢在线程池中注册计时器对象并且它负责处理回调(但这是另一个主题)。

    【讨论】:

    • 感谢您的解释:看看这里:msdn.microsoft.com/en-us/library/aa490206.aspx 它说计时器用作同步对象。还是我理解错了?
    • 是的,它们是“同步对象”,您可以使用它们同步多个线程的执行。然而,它们不以任何方式用于 NT 内核中的互斥或资源访问控制。为此,有信号量、事件和门(轻量级事件)。
    【解决方案2】:

    这是一种通过避免同时访问来进行同步的方法。访问基本上由序列化控制,序列化发生在通过回调调用的单个处理函数中,在本例中为计时器回调。见this

    管理访问的要点是防止两个线程同时访问(读取或写入)一个对象。有几种机制可以实现这一点:

    • 只有一个线程:不可能发生争用,因为只有一个参与者。
    • 互斥锁:一种操作系统机制与编码技术相结合,以形式化访问,以便每次线程说我想要控制互斥锁。当授予控制权时,这意味着在互斥锁的所有者释放它之前,没有其他人可以访问关联的对象。
    • 序列化:这类似于只有一个线程。一个典型的方案允许对请求进行排队。一旦完成更高优先级的请求,就会处理您的请求。在您完成之前,不会处理对该对象的其他请求。

    【讨论】:

    • 感谢您的链接。这很困难,我对所有这些内核的东西还是比较陌生,所以你能详细说明一下你的解释吗?
    • 我已经扩展了它。看看这是否还有帮助。
    • 谢谢你的解释,但这种情况下的计时器对象不是用于锁定的对象吗?就像互斥锁一样?
    【解决方案3】:

    您必须以这种方式查看它:当您在等待计时器时,您正在同步计时器到期。在计时器指定的到期时间过去之前,您的线程不会运行(取决于系统时间的粒度,通常为 15.6 毫秒)。

    一般而言,将计时器称为“同步对象”更多地与您用于在线程上找出其到期时间的 API 系列有关,而不是对象本身的实际功能。

    通常在内核模式下,计时器到期实际上是使用 DPC 回调来消耗的(请参阅 KeSetTimer 的 DPC 参数)。这只是一个异步调用,它发生在内核中的某个任意线程上下文中,您可以在其中运行代码(但它不能阻塞、获取锁、访问可分页内存等)。后一种限制对于设备驱动程序来说并不是真正的问题,他们大多只想定期触摸他们的设备。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-29
      • 2021-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多