Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1951194
  • 博文数量: 383
  • 博客积分: 10011
  • 博客等级: 上将
  • 技术积分: 4061
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-24 18:53
文章分类

全部博文(383)

文章存档

2011年(1)

2010年(9)

2009年(276)

2008年(97)

我的朋友

分类: LINUX

2009-07-11 21:49:50

    在 Linux 内核中,各个子系统之间有很强的相互关系,一些被一个子系统生成或者被探测到的事件,很可能是另一个或者多个子系统感兴趣的,也就是说这个事件的获取者必须能够通知所有对该事件感兴趣的子系统,并且还需要这种通知机制具有一定的通用性。基于这些, Linux 内核引入了“通知链”技术。

1 数据结构:

通知链有四种类型,

  1. 原子通知链( Atomic notifier chains ):通知链元素的回调函数(当事件发生时要执行的函数)只能在中断上下文中运行,不允许阻塞
  2. 可阻塞通知链( Blocking notifier chains ):通知链元素的回调函数在进程上下文中运行,允许阻塞
  3. 原始通知链( Raw notifier chains ):对通知链元素的回调函数没有任何限制,所有锁和保护机制都由调用者维护
  4. SRCU 通知链( SRCU notifier chains ):可阻塞通知链的一种变体

所以对应了四种通知链头结构:

  • struct atomic_notifier_head :原子通知链的链头
  • struct blocking_notifier_head :可阻塞通知链的链头
  • struct raw_notifier_head :原始通知链的链头
  • struct srcu_notifier_head : SRCU 通知链的链头

通知链元素的类型:

  • struct notifier_block :通知链中的元素,记录了当发出通知时,应该执行的操作(即回调函数)

链头中保存着指向元素链表的指针。通知链元素结构则保存着回调函数的类型以及优先级,参见 notifier.h 文件。

2 运作机制

通知链的运作机制包括两个角色:

  1. 被通知者:对某一事件感兴趣一方。定义了当事件发生时,相应的处理函数,即回调函数。但需要事先将其注册到通知链中(被通知者注册的动作就是在通知链中增加一项)。
  2. 通知者:事件的通知者。当检测到某事件,或者本身产生事件时,通知所有对该事件感兴趣的一方事件发生。他定义了一个通知链,其中保存了每一个被通知者对事件的处理函数(回调函数)。通知这个过程实际上就是遍历通知链中的每一项,然后调用相应的事件处理函数。

包括以下过程:

  1. 通知者定义通知链
  2. 被通知者向通知链中注册回调函数
  3. 当事件发生时,通知者发出通知(执行通知链中所有元素的回调函数)

被通知者调用 notifier_chain_register 函数注册回调函数,该函数按照优先级将回调函数加入到通知链中 。注销回调函数则使用 notifier_chain_unregister 函数,即将回调函数从通知链中删除。2.2.1节讲述的4种通知链各有相应的注册和注销函数,但是他们最终都是调用上述两个函数完成注册和注销功能的。有兴趣的读者可以自行查阅内核代码。

通知者调用 notifier_call_chain 函数通知事件的到达,这个函数会遍历通知链中所有的元素,然后依次调用每一个的回调函数(即完成通知动作)。2.2.1节讲述的4种通知链也都有其对应的通知函数,这些函数也都是最终调用 notifier_call_chain 函数完成事件的通知。

由以上的叙述,“通知链”技术可以概括为:事件的被通知者将事件发生时应该执行的操作通过函数指针方式保存在链表(通知链)中,然后当事件发生时通知者依次执行链表中每一个元素的回调函数完成通知。

阅读(1035) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~