Chinaunix首页 | 论坛 | 博客
  • 博客访问: 982682
  • 博文数量: 186
  • 博客积分: 10020
  • 博客等级: 上将
  • 技术积分: 1676
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-14 17:08
文章存档

2011年(5)

2009年(11)

2008年(2)

2007年(111)

2006年(57)

我的朋友

分类: LINUX

2006-09-04 15:45:42

   内核编程中常见的一种模式是,在当前线程只外初始化某个活动,然后等待该活动的结束。这个活动可能是,创建一个新的内核线程或者新的用户空间进程,在这种情况下,我们可以使用信号量来同步这两个任务
    struct semaphore sem;
    init_MUTEX_LOCKED(&sem);
    start_external_task(&sem);
    down(&sem);
    外部任务working。。。。。
    up(&sem);
 
使用信号的缺点:在通常的使用中,试图锁定某个信号量的代码会发现该信号量几乎总是可用;而如果存在针对该信号量的严重竞争,性能将受到影响(像上面那种情况,使用信号量在任务完成时进行通信,则调用down的线程几乎总是要等待)
 
目前,从2.4版内核开始,到2.6已经出现了"completion(完成)"接口。
completion是一种轻量级的机制,它允许一个线程告诉另一个线程某个工作已经完成
 DECLARE_COMPLETION(my_completion); /* 创建completion */
 
/* 动态地创建和初始化completion */
 struct completion my_completion;
 init_completion(&my_completion);
 
/* 该函数执行一个非中断的等待,如果没有人会完成任务,则将产生一个不可杀的进程*/
 void wait_for_completion(struct completion *c);
 
/* 触发实际的completion事件(completion通常是一个单次设备) */
 void complete(struct completion *c); /*只唤醒一个等待进程*/
 void complete_all(struct completion *c); /*允许唤醒所有等待进程*/
 
如果需要重复使用completion结构:
 1.complete()使用完completion设备一次后然后被丢弃,如果仔细处理,completion结构也可以被重复使用,如果没有使用complete_all(),只要那个将要触发的事件是明确而不含糊的,就不会来任何问题,可重复使用一个completion结构.
 2. 如果使用了complete_all,则必须在重复使用该结构之前重新初始化它,可以调用下面这个宏来快速执行重新初始化:
   INIT_COMPLETION(struct completion c);
 
completion机制的典型使用是模块退出时的内核线程终止
当内核准备清除该模块时,exit函数会告诉该线程(内核线程while(1)循环)退出并等待completion,为了实现这个目的,内核包含了一个可用于这种线程的函数:
 void complete_and_exit(struct completion *c,long retval);
  有兴趣的朋友大家可以一起探讨
阅读(1052) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~