cmqy 发表于 2016-04-11 11:54

睡眠功能的实现

睡眠功能的实现,摘录自LDD3
睡眠的步骤
1、分配并初始化一个wait_queue_t结构,然后将其加入到对应的等待队列中
2、设置进程的状态,在<linux/sched.h>中定义了很多状态,有两个是睡眠状态TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE

操作进程状态:
        void set_current_state(int new_state);
        或者,current->TASK_INTERRUPTIBLE;
上述只是修改了调度器处理其的方式,并未进入休眠状态

放弃处理器:
        在这个步骤之前,应该检查休眠的等待条件等,否则可能会丢失**
        if(!condition)                //如果**发生在if和schedule之间,那么不会有任何影响,因为**会把进程状态设置为TASK_RUNNING
                schedule();


如果条件为真而没有调用schedule(),应该修改进程状态,并且从等待队列中移走,否则会被多次**。从schedule()中返回则不用手动修改

实现代码:
        创建并初始化一个等待队列entry
                DEFINE_WAIT(my_wait)
                或者:
                wait_queue_t my_wait
                init_wait(&my_wait)
       
        添加等待队列entry到队列
                void prepare_to_wait(wait_queue_head_t *queue, wait_queue_t *wait, int state);
               
        之后便可调用schedule()
       
        清理
                void finish_wait(wait_queue_head_t *queue, wait_queue_t *wait);
               
               
               
独占等待:
        wake_up会**等待队列中的所有进程,但通常只有一个进程会得到资源,造成大量进程再次进入休眠。
        可以在等待队列entry中设置WQ_FLAG_EXCLUSIEV标志。有这个标志的进程会添加到队列尾部,没有的会添加到队列头部。每次wake_up**所有不带的,和一个带的
       
        prepare_to_wait_exclusive实现独占等待的便捷方式,wait_event无法实现独占等待
       
       
**细节
        wake_up                **所有非独占和一个独占
        wake_up_interruptible        和wake_up相同的作用,但会跳过不可中断休眠的进程
                这两个函数在返回前让**的一个或多个进程被调度,但在原子上下文中调用时不会发生
               
        wake_up_nr
        wake_up_interruptible_nr
                只**nr个,0则**全部
               
        wake_up_interruptible_sync        通常,被**的进程可能会抢占当前进程,在wake_up返回前被调度到处理器,这一函数避免这种情况
       
       
       
wait_event 是对prepare_to_wait、schedule、finish_wait的封装,会直到条件成立才返回

sleep_on和interruptible_sleep_on是不安全的,永远不要使用它们
页: [1]
查看完整版本: 睡眠功能的实现