阻塞访问时:
当应用程序对设备驱动进行操作的时候,如果不能获取到设备资源,那么阻塞式 IO 就会将应用程序对应的线程挂起,直到设备资源可以获取为止。阻塞访问最大的好处就是当设备文件不可操作的时候进程可以进入休眠态,这样可以将CPU 资源让出来。但是,当设备文件可以操作的时候就必须唤醒进程,一般在中断函数里面完成唤醒工作。Linux 内核提供了等待队列(wait queue)来实现阻塞进程的唤醒工作,对于设备驱动文件的默认读取方式就是阻塞式的。方法是先初始化等待队列头,然后把work加入到等待队列项add_wait_queue,在驱动read里等待(wait_event_interrupt),而后在中断函数中唤醒线程(wake_up)
非阻塞访问时:
使用poll或者select或者epoll
应用程序使用poll函数调用file_operation中的poll,根据驱动中poll返回值判断是否条件满足进而执行read
poll返回值:
成功时(>0),poll()返回结构体中revents域不为0的文件描述符个数(其中 revents可以取值为POLL_IN或者POLL_OUT等等);如果在超时前没有任何事件发生,poll()返回0;失败时,poll()返回-1
注意所谓的非阻塞指的是应用层仍然在死循环中不断调用poll函数,但是驱动的poll函数中会卡在poll_wait那,但是不会一直卡死,一旦超时或者条件满足就会返回到应用层,所以说过程中也会有阻塞,只是阻塞的时间有限制而已,总体看上去好像一直在不断查看(非阻塞)
非阻塞体现在在timeout这个超时上。