睡眠功能的实现
睡眠功能的实现,摘录自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]