中断处理之三:阻塞型I/O

应用程序向硬件请求数据的时候,硬件那不一定有数据上来。怎么办呢?

简单的想法就是忙等。这样效率低,所以这里就介绍一下Linux中的阻塞型输入输出。

wait_queue_heat_t结构体

这个结构体是用来管理睡眠唤醒的条件的。不同的等待事件我们要为其创建不同的等待队列。

定义等待队列方法如下:

wait_queue_head_t sample_wait_queue;
init_waitqueue_head(sample_wait_queue);

或者

DECLARE_WAIT_QUEUE_HEAD(sample_wait_queue);

如何使用?

使用方法比较简单,在先定义了等待队列之后

当进程需要睡眠的时候(比如等待数据的到来)就调用

interruptible_sleep_on(&sample_wait_queue);

来使得当前进程睡眠;

当数据来的时候就调用

wake_up_interruptible(&sample_wait_queue);

唤醒进程。

这里有一个问题:要在哪里唤醒进程呢

答案是:在中断处理函数中,在有数据来的时候,会发生中断,这时候中断处理函数就会被调用(当然你要申请过IRQ并且注册了该中断处理函数)

所以就会经常看到这样结构的代码:

/* 中断处理函数 */
void XXX_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
    /* … */
    wake_up_interrupt(&waitqueue);

    /* … */
}

/* 阻塞式读入 */
ssize_t XXX_read(struct file *filp, char *buf, size_t count,
                  loff_t *f_ops)
{
    /* … */
    interruptible_sleep_on(&waitqueue);
   
    /* … */
}