linux驱动--阻塞和非阻塞 I/O

来源:互联网 发布:淘宝刷好评犯法吗 编辑:程序博客网 时间:2024/04/28 10:54

1、阻塞和非阻塞 I/O

定义:

阻塞:指在执行设备操作时,若不能获得资源则挂起进程,知道满足可操作的条件后再进行操作。被挂起的进程进入休眠状态,被从调度器的运行队列中移走,直到等待条件的满足。

非阻塞:非阻塞操作的进程在不能满足操作时并不挂起,它或者放弃,或者不停地查询,知道可以进行操作为止。

1.1 等待队列

作用:可以用等待队列(wait queue)来实现阻塞进程的唤醒

(1)  定义“等待队列头”

wait_queue_head_t   my_queue;

(2) 初始化“等待队列头”

init_waitqueue_head(&my_queue);

(3) 定义等待队列

DECLARE_WAIT_QUEUE_HEAD(name)

(4) 添加/移除等待队列

void fastcall add_wait_queue(wait_queue_head_t *q,wait_queue_t *wait);

void fastcall remove_wait_queue(wait_queue_head_t *q,wait_queue_t *wait);

(5) 等待事件

wait_event(queue,condition)

wait_event_interruptible(queue,condition)

wait_event_timeout(queue,condition,timeout)

wait_event_interruptible_timeout(queue,condition,timeout)

注意:timeout 意味着等到的超时时间,当到达时间时,不管是否满足,均返回。

(5) 唤醒队列

void wake_up(wait_queue_head_t *queue);

void wake_up_interruptible(wait_queue_head_t *queue);

 成对出现:

A. wake_up() 和 wait_event() 或 wait_event_timeout() 成对使用

B. wake_up_interruptible()和wait_event_interruptible或者wait_event_interruptible_timeout()成对使用

注意:

1、wake_up()可以唤醒处于TASK_INTERRUPTIBLE 和TASK_UNINTERRUPTIBLE的进程(他们处于休眠状态)

2、wake_up_interruptible()只能唤醒处于TASK_INTERRUPTIBLE的进程

(6)在等待队列上睡眠

sleep_on(wait_queue_head_t *q);

interruptible_sleep_on(wait_queue_head_t *q);

1.2 支持阻塞操作的globalfifo设备驱动

 条件:首先把globalfifo全局内存变成一个FIFO,类似管道技术,只有往fifo中写入数据,才能从fifo中读出数据。

 在驱动程序read() 、write()函数中,filp->f_flags标志是否使用非阻塞方式访问。

1.3  在用户空间验证globalfifo的读写

每当echo进程向/dev/globalfifo(即设备文件)写入一串数据时,cat进程就立即将该串显示出来

2、轮询操作

2.1 轮训的概念和作用

应用程序通常会使用select()和poll()系统调用查询是否对设备进行阻塞访问

2.2 应用程序中的轮询编程

函数1:select()函数

struct timeval

{

int tv_sec;

int tv_usec;

};

FD_ZERO();   清楚一个文件描述符

FD_SET();  将一个文件描述符加入文件描述符集中

FD_CLR();将一个文件描述符从文件描述符集中清楚

FD_ISSET();判断文件描述符是否被置位

2.3 设备驱动中轮询编程

函数1:poll()函数--

函数2:poll_wait()函数-->作用:把当前进程添加到等待队列的(poll_table)中

2.4 支持轮询操作的globalfifo驱动

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

原创粉丝点击