Linux 阻塞和非阻塞IO开发及异步通知技术

271 阅读2分钟

1 阻塞和非阻塞 IO

image.png

  • 阻塞模式访问 image.png image.png
  • 非阻塞模式访问 image.png
  • 阻塞访问最大的好处就是当设备文件不可操作的时候进程可以进入休眠态,这样可以将CPU 资源让出来。但是,当设备文件可以操作的时候就必须唤醒进程,一般在中断函数里面完成唤醒工作。Linux 内核提供了等待队列(wait queue)来实现阻塞进程的唤醒工作,如果我们要在驱动中使用等待队列,必须创建并初始化一个等待队列头,等待队列头使用结构体wait_queue_head 表示,wait_queue_head 结构体定义在文件 include/linux/wait.h 中 image.png image.png image.png image.png

2 阻塞IO

  • 读等待队列头 image.png
  • 阻塞唤醒 image.png
  • 按键读取应用程序阻塞 image.png
  • 应用程序 image.png image.png

3 非阻塞IO

image.png image.png

  • 驱动程序的 poll 函数中调用 poll_wait 函数判断是否可以读取,如果可以读取的话就调用 read 函数读取按键数据) image.png
  • 在本测试程序中我们使用 select 函数来实现非阻塞访问,在 for 循环中使用select 函数不断的轮询,检查驱动程序是否有数据可以读取,如果可以读取的话就调用 read 函数读取按键数据image.png
  • 从设备读取数据,条件是驱动程序的 poll 函数返回 POLLIN | POLLRDNORM image.png
  • 应用程序非阻塞IO访问(如果可以读取的话image.png
  • 结果 image.png

4 异步通知

  • Linux 应用程序可以通过阻塞或者非阻塞这两种方式来访问驱动设备,通过阻塞方式访问的话应用程序会处于休眠态,等待驱动设备可以使用。
  • 非阻塞方式的话会通过 poll 函数来不断的轮询,查看驱动设备文件是否可以使用。这两种方式都需要应用程序主动的去查询设备的使用情况,
  • 如果能提供一种类似中断的机制,当驱动程序可以访问的时候主动告诉应用程序那就最好了。

4.1 信号类型

image.png image.png

  • CTRL+C发送SIGINT信号 image.png image.png image.png image.png

4.2 驱动程序编写

  • 定义异步通知设备结构体 image.png
  • 按键唤醒,异步通知 image.png image.png image.png image.png
  • read image.png
  • fasync函数,用于处理异步通知 image.png image.png image.png

4.3 应用程序编写

image.png image.png