Chinaunix首页 | 论坛 | 博客
  • 博客访问: 162752
  • 博文数量: 40
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 355
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-27 18:05
文章分类
文章存档

2011年(1)

2010年(9)

2009年(16)

2008年(14)

我的朋友

分类: LINUX

2008-12-09 09:59:09

linux/wait.h

非阻塞设置的标志:O_NONBLOCK,O_NDELAY

非阻塞:只对 read, write,open 操作有影响
        read, write非阻塞 返回 -EAGAIN,
        open非阻塞 返回-EBUSY ,特别的语义(磁带)非阻塞标志打开时立刻成

             功,不管是否介质在或不在正常open时,常常阻塞直到插入一个磁带



简单睡眠
DECLARE_WAIT_QUEUE_HEAD(name);
或者动态地, 如下:
wait_queue_head_t my_queue;
init_waitqueue_head(&my_queue);

wait_event(queue, condition)
wait_event_interruptible(queue, condition)
wait_event_timeout(queue, condition, timeout)
wait_event_interruptible_timeout(queue, condition, timeout)
//wait_event不可中断地睡眠
//wait_event_interruptible若返回非零值,则检查是否由于被信号中断,你的函数返回-ERESTARTSYS
//wait_event_timeout 和 wait_event_interruptible_timeout超时后返回0


void sleep_on(wait_queue_head_t *queue);
void interruptible_sleep_on(wait_queue_head_t *queue);
//无条件地使当前进程睡眠在给定队列上,强烈不推荐使用


void wake_up(wait_queue_head_t *queue);
void wake_up_interruptible(wait_queue_head_t *queue);
wake_up_nr(wait_queue_head_t *queue, int nr);
wake_up_interruptible_nr(wait_queue_head_t *queue, int nr);
wake_up_all(wait_queue_head_t *queue);
wake_up_interruptible_all(wait_queue_head_t *queue);
wake_up_interruptible_sync(wait_queue_head_t *queue);
//wake_up 唤醒不是在互斥等待中、处于不可中断的进程????
//wake_up_interruptible唤醒不是在互斥等待、处于可中断的所有进程????
//wake_up_nr和wake_up_interruptible_nr唤醒多达 nr 个互斥等待者,0 为所有互斥等待者被唤醒
//wake_up 唤醒所有的进程
//wake_up_all唤醒所有的进程,跳过可中断等待的进程
//wake_up_interruptible_sync保证无论是否在原子操作,在唤醒返回后,本进程的调度不会被新唤醒的进程抢占,本进程依然运行。

高级睡眠
睡眠原理

     1.分配和初始化一个 wait_queue_t 结构, 添加到正确的等待队列  wait_queue_head_t
     2.设置进程的状态来标志它为睡眠,TASK_RUNNING 意思是进程能够运行, 睡眠TASK_INTERRUPTIBLE 和 TASK_UNTINTERRUPTIBLE,其他的状态正常地和驱动编写者无关
          2.6 内核void set_current_state(int new_state);
          老代码current->state = TASK_INTERRUPTIBLE;


    3.检查睡眠条件,放弃处理器
     if (!condition)
          schedule();
    4.若条件满足,成功休眠后,必须保证任务状态被重置为TASK_RUNNING
     若条件不满足,必须从等待队列中去除这个进程, 否则它可能被多次唤醒


手动睡眠linux/sched.h
    1. DEFINE_WAIT(my_wait);
        //

        wait_queue_t my_wait;
        init_wait(&my_wait);
         //
      2.添加你的等待队列入口到队列, 并且设置进程状态
       void prepare_to_wait(wait_queue_head_t *queue, wait_queue_t

                 *wait, int state); 
       void prepare_to_wait_exclusive(wait_queue_head_t *queue,

                 wait_queue_t *wait, int state);

         // WQ_FLAG_EXCLUSEVE设置prepare_to_wait_exclusive的state为

           可中断的互斥等待,简单休眠不可以设置。
      3.检查条件,调用 schedule
           if (!condition)
               schedule();
       4.清理
       void finish_wait(wait_queue_head_t *queue, wait_queue_t

           *wait);

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