您的位置:首页 > 运维架构 > Linux

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

2013-02-20 16:39 148 查看
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驱动
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: