Linux 睡眠与唤醒
现实中,很容易理解睡眠与唤醒的意思。这一概念如何应用到操作系统中的呢?首先明白睡眠与唤醒的“主体”是进程,也就是说进程睡眠与唤醒。其次需要了解什么”条件“导致其睡眠与唤醒。1.Linux中进程睡眠含义与实现睡眠的说法有很多,例如挂起,阻塞等,其实本质就是主体(进程)所处的一种状态,可以通过状态描述 TASK_INTERRUPTIBLE, TASK_UNINTERRUPTIBLE。 具体实现
·
现实中,很容易理解睡眠与唤醒的意思。这一概念如何应用到操作系统中的呢?首先明白睡眠与唤醒的“主体”是进程,也就是说进程睡眠与唤醒。其次需要了解什么”条件“导致其睡眠与唤醒。
1.Linux中进程睡眠含义与实现
睡眠的说法有很多,例如挂起,阻塞等,其实本质就是主体(进程)所处的一种状态,可以通过状态描述 TASK_INTERRUPTIBLE, TASK_UNINTERRUPTIBLE。 具体实现通过等待队列与运行队列(数据结构)来实现的,首先把进程标识为睡眠状态,其次添加到等待队列,最后从运行队列选择其他进程运行。
1)算法头文件
<linux/wait.h>
2)等待队列数据结构为:
wait_queue_head_t
3)等待队列的初始化
静态(编译时)初始化
DECLEAR_WAIT_QUEUE_HEAD(wqueue);
动态(运行时)初始化
wait_queue_head_t wqueue;
init_waitqueue_head(&wqueue)
4)添加到等待队列中
add_wait_queue(&video->waitq, &wait);
5)标记进程为睡眠状态
set_current_state(TASK_INTERRUPTIBLE);
6)自旋锁非常重要,主要保护条件“video->frames[video->first_clear_frame]->state != FRAME_CLEAR”并发访问,当两个进程被唤醒时,两个进程看到该条件成立,导致冲突。
spin_lock_irqsave(&video->spinlock, flags);
7)如果条件不成立,进行睡眠,从运行队列选择其他进程运行。
/* wait until video->first_clear_frame is really CLEAR */
while (video->frames[video->first_clear_frame]->state != FRAME_CLEAR) {
spin_unlock_irqrestore(&video->spinlock, flags);
如果由于信号唤醒,那么首先从等待队列把进程删除,然后设置进程运行状态
if (signal_pending(current)) {
remove_wait_queue(&video->waitq, &wait);
set_current_state(TASK_RUNNING);
ret = -EINTR;
goto out;
}
schedule();
set_current_state(TASK_INTERRUPTIBLE);
spin_lock_irqsave(&video->spinlock, flags);
}
spin_unlock_irqrestore(&video->spinlock, flags);
8)如果由于条件成立唤醒进程,首先从等待队列把进程删除,然后设置进程运行状态
remove_wait_queue(&video->waitq, &wait);
set_current_state(TASK_RUNNING);
2.Linux中进程唤醒含义与实现
1.Linux中进程睡眠含义与实现
睡眠的说法有很多,例如挂起,阻塞等,其实本质就是主体(进程)所处的一种状态,可以通过状态描述 TASK_INTERRUPTIBLE, TASK_UNINTERRUPTIBLE。 具体实现通过等待队列与运行队列(数据结构)来实现的,首先把进程标识为睡眠状态,其次添加到等待队列,最后从运行队列选择其他进程运行。
1)算法头文件
<linux/wait.h>
2)等待队列数据结构为:
wait_queue_head_t
3)等待队列的初始化
静态(编译时)初始化
DECLEAR_WAIT_QUEUE_HEAD(wqueue);
动态(运行时)初始化
wait_queue_head_t wqueue;
init_waitqueue_head(&wqueue)
4)添加到等待队列中
add_wait_queue(&video->waitq, &wait);
5)标记进程为睡眠状态
set_current_state(TASK_INTERRUPTIBLE);
6)自旋锁非常重要,主要保护条件“video->frames[video->first_clear_frame]->state != FRAME_CLEAR”并发访问,当两个进程被唤醒时,两个进程看到该条件成立,导致冲突。
spin_lock_irqsave(&video->spinlock, flags);
7)如果条件不成立,进行睡眠,从运行队列选择其他进程运行。
/* wait until video->first_clear_frame is really CLEAR */
while (video->frames[video->first_clear_frame]->state != FRAME_CLEAR) {
spin_unlock_irqrestore(&video->spinlock, flags);
如果由于信号唤醒,那么首先从等待队列把进程删除,然后设置进程运行状态
if (signal_pending(current)) {
remove_wait_queue(&video->waitq, &wait);
set_current_state(TASK_RUNNING);
ret = -EINTR;
goto out;
}
schedule();
set_current_state(TASK_INTERRUPTIBLE);
spin_lock_irqsave(&video->spinlock, flags);
}
spin_unlock_irqrestore(&video->spinlock, flags);
8)如果由于条件成立唤醒进程,首先从等待队列把进程删除,然后设置进程运行状态
remove_wait_queue(&video->waitq, &wait);
set_current_state(TASK_RUNNING);
2.Linux中进程唤醒含义与实现
Linux中进程唤醒就是从上述睡眠的等待队列中,把由于所有进程状态设置为运行,同时把起进程放入运行队列,将来某一时间,调度程序会选择运行此程序。
该程序会继续执行上面睡眠之后代码,即(7)(8).再次设置进程状态,从等待队列中删除。
唤醒函数接口非常简单:
更多推荐
已为社区贡献1条内容
所有评论(0)