linux设备驱动中的阻塞和非阻塞IO

一、等待队列
1、定义等待队列头
wait_queue_head_t my_queue;
2、初始化等待队列头
init_waitqueue_head(&my_queue);
3、定义等待队列
DECLARE_WAITQUEUE(name,tsk);
4、添加/移除等待队列
void fatcall add_wait_queue(wait_queue_head_t *q,wait_queue_t *wait);
void fatcall remove_wait_queue(wait_queue_head_t *q,wait_queue_t *wait);
5、等待事件
wait_event(queue,condition);
wait_event_inturruptible(queue,condition);
wait_event_timeout(queue,condition,timeout);
wait_event_inturruptible_timeout(queue,condition,timeout);
6、唤醒等待队列
void wake_up(wait_queue_head_t *queue);
void wake_up_interruptible(wait_queue_head_t *queue);
7、在等待队列上睡眠
sleep_on(wait_queue_head_t *queue);
interruptible_sleep_on(wait_queue_head_t *queue);
8、等待队列的使用
tatic ssize_t xxx_write(struct file *file,const char *buffer,ssize_t count,loff_t *ppos)
{
....
DECLARE_WAITQUEUE(wait,current);//定义等待队列
add_wait_queue(&xxx_wait,&wait);//添加等待队列

ret=count;
//等待设备缓冲区可写
do{
avail=device_writable();
if(avail<0)
__set_curent_stats(TASK_INTERRUPTIBLE);//改变进程状态TASK_INTERRUPTIBLE

if(avail<0){
if(file->f_flags & O_NONBLOCK){//非阻塞
if(!ret)
ret=-EAGAIN;
goto out;
}
schedule();//调度其他进程
if(signal_pending(current)){
if(!ret)
ret=-ERESTARTSYS;
goto out;
}
}
}while(avail<0);

//写设备缓冲区
device_write()
out:
remove_wait_queue(&xxx_wait,&wait);//移除等待队列
set_current_state(TASK_RUNNING);//设置进程状态为TASK_RUNNING
}


二、轮询操作
1、应用程序中的轮询编程
int select(int numfd,fd_et *readfd,fd_set *writefds,fd_set *execptfds,struct timeval *timeout);
readfd:读文件描述符集合
writefds:写文件描述符集合
execptfds:异常处理文件描述符集合
2、文件描述符的操作
FD_ZERO(fd_set *set);//清楚一个文件描述符集合
FD_SET(int fd,fd_set *set);//将一个文件描述符加入到文件描述符集合中
FD_CLR(int fd,fd_set *set);//将一个文件描述符从文件描述符集合中移除
FD_ISSET(int fd,fd_set *set);//判断文件描述符是否置位


2、设备驱动中的轮询编程
unsigned int (*poll)(struct file *filp,struct poll_table *wait);
3、poll函数的模板
unsigned int (*poll)(struct file *filp,struct poll_table *wait)
{
unsigned int mask=0;
struct xxx_dev *dev=filp->private_data;//获得设备结构体指针
....
poll_wait(filp,&dev->r_wait,wait);//加入读等待队列
poll_wait(filp,&dev->w_wait,wait);//加入写等待队列

if(...)//可读
mask|=POLLIN | POLLRDNORM;

if(...)//可写
mask|=POLLIN | POLLWDNORM;

return mask;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值