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

本文深入探讨了Linux驱动中的阻塞IO操作,通过等待队列实现资源等待,并详细介绍了如何使用信号量进行同步。同时,阐述了轮询操作在用户空间的实现方式,包括如何通过select和poll系统调用监控文件描述符,并在设备驱动中实现poll函数。文章最后总结了阻塞IO与非阻塞IO的区别及应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.阻塞IO

linux驱动中,可使用等待队列实现阻塞I/O。信号量在内核中就是依赖等待队列来实现的。

等待队列:

//定义初始化‘等待队列头’

Wait_queue_head_t  my_queue

Init_wait_queue_head&my_queue);

DECLARE_WAIT_QUEUE_HEAD (name)

//定义并初始化一个等待队列

DECLARE_WAITQUEUE(name, tsk);

//将等待队列添加到等待队列头Q指向的等待队列链表中

Void fastcall add_wait_queuewait_queue_head_t *q, wait_queue_t *wait);

//将等待队列从等待队列头q指向的等待队列链表中移除

Void fastcall remove_wait_queuewait_queue_head_t *qwait_queue_t *wait);

//等待事件,queue为等待队列头,timeoutjiffy为单位

Wait_eventqueue, condition);

Wait_event_interruptiblequeue, condition);

Wait_event_timeoutqueue, condition, timeout);

Wait_event_interruptible_timeoutqueue, condition, timeout);

//唤醒队列

Void wake_upwait_queue_head_t *q);

Void wake_up_interruptible wait_queu_head_t *q);

注意:wake_up可唤醒wait_event或者wait_event_interruptible,但是    wake_up_interruptible只能唤醒wait_event_interruptible

//在等待队列上睡眠

Sleep_onwait_queue_head_t *q);

Interruptible_sleep_onwait_queue_head_t *q);

注意:sleep_on或者interruptible_sleep_on函数的作用就是将目前进程的状态设置成TASK_UNINTERRUPTIBLE或者INTERRUPTIBLE。并定义一个等待队列,之后把它附属到等待队列头q,直到资源可获得,q引导的队列别唤醒或者接到信号。Sleep_on函数应该与wake_up成对使用,interruptible_sleep_on应该与wake_up_interruptble 成对使用。


set_current_state()(设置当前进程的运行状态)和signal_pending();current代表当前进程。

166页的例子。

需要特别注意的一点:当等待队列和信号量同时出现时,一定要注意是否会发生死锁。当进去等待时,看是否还持有别的进程需要的信号量。切记、切记。

.

2.轮询操作:

用户空间会调用selectpoll对文件描述符进行监控。Select()和poll()系统调用最终会引发设备驱动中的poll()函数被执行。设备驱动中poll()函数的原型是:

Unsigned int *poll)(struct file *filep, struct poll_table *wait);

(1)对可能引起设备文件状态变化的等待队列头调用poll_wait()函数将对应的等待队列头添加到poll_table

(2)返回表示是否能对设备进行无阻塞读、写访问的掩码。

用于向poll_table注册等待队列的poll_wait()函数的原型如下:

Void poll_waitstruct file *filep, wait_queue_head_t *queue, poll_table *wait);

173页例子

总结:设备驱动中阻塞IO一般基于等待队列来实现。非阻塞IO会调用驱动中提供的poll函数。设备驱动中的poll()本身不会阻塞,但是select()和poll()系统调用则会等待文件描述符集合中的至少一个可访问或超时。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值