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); |