现在的位置: 首页 > 综合 > 正文

阻塞IO

2013年08月26日 ⁄ 综合 ⁄ 共 1826字 ⁄ 字号 评论关闭

 

大部分驱动需要 -- 除了读写设备的能力 -- 通过设备驱动进行各种硬件控制的
能力
1.在用户空间, ioctl 系统调用有下面的原型:
int ioctl(int fd, unsigned long cmd, ...);
2.ioctl 驱动方法有和用户空间版本不同的原型:
int (*ioctl) (struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg);
inode 和 filp 指针是对应应用程序传递的文件描述符 fd 的值, 和传递给
open 方法的相同参数. cmd 参数从用户那里不改变地传下来, 并且可选的参数
arg 参数以一个 unsigned long 的形式传递, 不管它是否由用户给定为一个整数
或一个指针.
-------------------------------------------------
对于一个 Linux 驱动使一个进程睡眠是一个容易做的事情. 但是, 有几个规则
必须记住以安全的方式编码睡眠
1.当你运行在原子上下文时不能睡眠.
一个原子上下文只是一个状态, 这里多个步骤必须在没有任何类型
的并发存取的情况下进行这意味着, 对于睡眠, 是你的驱动在持有一个自旋锁,seqlock, 或者 RCU 锁时不能睡眠. 如果你已关闭中断你也不能睡眠
2.使你的进程可能被找到, 真正地, 通过一个称为等待队列的数据结
构实现的. 一个等待队列就是它听起来的样子:一个进程列表, 都等待一个特定的事件.
3.用等待队列wait_queue来实现阻塞进程的唤醒,实现内核中异步事件的通知机制,可以同步对系统资源的访问
4.在 Linux 中, 一个等待队列由一个"等待队列头"来管理, 一个wait_queue_head_t 类型的结构, 定义在<linux/wait.h>
1)定义“等待队列头”
wait_queue_head_t my_queue;
2)初始化等待队列头
init_waitqueue_head(&my_queue);
或者DECLARE_WAIT_QUEUE_HEAD(name);
3)定义等待队列
DECLARE_WAITQUEUE(name,tsk);
该宏用于定义并初始化一个名为name的等待队列
4)Linux内核中睡眠的最简单方式是一个宏定义, 称为 wait_event(有几个变体);
wait_event(queue, condition);不可中断地睡眠
wait_event_interruptible(queue, condition);可中断地睡眠
wait_event_timeout(queue, condition, timeout)
wait_event_interruptible_timeout(queue, condition, timeout)
在所有上面的形式中, queue 是要用的等待队列头. 注意它是"通过值"传递的.
条件是一个被这个宏在睡眠前后所求值的任意的布尔表达式; 直到条件求值为真值, 进程继续睡眠.
5)唤醒睡眠进程的函数称为 wake_up
void wake_up(wait_queue_head_t *queue);
void wake_up_interruptible(wait_queue_head_t *queue);
-----------------------------------------------------------
1.如果一个进程调用 read 但是没有数据可用(尚未), 这个进程必须阻塞.这个进程在有数据达到时被立刻唤醒, 并且那个数据被返回给调用者, 即便小于在给方法的 count 参数中请求的数量.
2.如果一个进程调用 write 并且在缓冲中没有空间, 这个进程必须阻塞,并且它必须在一个与用作 read 的不同的等待队列中
3.在驱动中实现输出缓冲所获得的性能来自减少了上下文切换和用户级/内核级切换的次数
4.只有 read, write, 和 open 文件操作受到非阻塞标志影响O_NONBLOCK
5.一个进程如何睡眠
1)使一个进程睡眠的第一步常常是分配和初始化一个 wait_queue_t 结构, 随后将其添加到正确的等待队列
2)下一步是设置进程的状态来标志它为睡眠. 在 <linux/sched.h> 中定义有几个任务状态.TASK_RUNNING 意思是进程能够运行,TASK_INTERRUPTIBLE 和TASK_UNTINTERRUPTIBLE
6.调用 schedule , 当然, 是引用调度器和让出 CPU 的方式.

 

 

 

 

 

 

 

 

 

抱歉!评论已关闭.