Linux设备驱动中的阻塞与非阻塞总结

阻塞操作是指,在执行设备操作时,若不能获得资源,则进程挂起直到满足可操作的条件再进行操作。

非阻塞操作的进程在不能进行设备操作时,并不挂起。被挂起的进程进入sleep状态,被从调度器的运行队列移走,直到等待的条件被满足。

阻塞与非阻塞访问是I/O操作的两种不同模式,前者在I/O操作暂时不可进行时会让进程睡眠。

在设备驱动中阻塞I/O一般基于等待队列来实现,等待队列可用于同步驱动中事件发生的先后顺序。

使用非阻塞I/O的应用程序也可借助轮询函数来查询设备是否能立即被访问。

阻塞操作是指在设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作。被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件满足。

非阻塞操作的进程在不能进行设备操作时并不挂起,它或者放弃,或者不停地查询,直到可进行操作为止。

等待队列:

等待队列的操作:

// 定义“等待队列头”

wait_queue_head_t my_queue;

// 初始化“等待队列头”

init_wait_queue_head(&my_queue);

// 定义并初始化等待队列头的快捷方式(宏)

DECLARE_WAIT_QUEUE_HEAD(name)

// 定义等待队列

DECLARE_WAITQUEUE(name, tsk) // 该宏用于定义并初始化一个名为name的等待队列

//添加/移除等待队列

void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait); // 将等待队列wait添加到等待队列头q指向的等待队列链表中

void fastcall remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait); // 将等待队列wait从附属的等待队列头q指向的等待队列链表中移除

// 等待事件

wait_event(queue, condition) // queue作为等待队列头的等待队列被唤醒,而且condition必须满足,否则阻塞。不能被信号打断

wait_event_interruptible(queue, condition) // 可以被信号打断

wait_event_timeout(queue, condition) // 加上_timeout后意味着阻塞等待的超时时间,以jiffy为单位。在timeout到达时不论condition是否满足,均返回

wait_event_interruptible_timeout(queue, condition)

// 唤醒队列

// 唤醒以queue作为等待队列头的所有等待队列中所有属于该等待队列头的等待队列对应的进程

void wake_up(wait_queue_head_t *queue);

void wake_up_interruptible(wait_queue_head_t *queue);

// wake_up()应与wait_event()或wait_event_timeout()成对使用

// 而wake_up_intterruptible()则应与wait_event_interruptible()或wait_envent_interruptible_timeout()成对使用

// wake_up()可唤醒处于TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE的进程,而wake_up_interruptible()只能唤醒处于TASK_INTERRUPTIBLE的进程

// 在等待队列上睡眠

sleep_on(wait_queue_head_t *q); // 将目前进程的状态设置成TASK_UNINTERRUPTIBLE,并定义一个等待队列,之后把它附属到等待队列头q,

// 直到资源可获得,q引导的等待队列被唤醒。

interruptible_seep_on(wait_queue_head_t *q); // 将目前进程的状态设置成TASK_INTERRUPTIBLE,并定义一个等待队列,之后把它附属到等待队列头q,

// 直到资源可获得,q引导的等待队列被唤醒或者进程收到信号。

轮询操作:

使用非阻塞I/O的应用程序通常使用select()和poll()系统调用查询是否可对设备进行无阻塞的访问。select()和poll()系统调最终会引发设备中的poll()函数执行(xxx_poll()).

应用程序中的轮询编程:

select()系统调用:

int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

其中readfds、writefds、exceptfds分别是被select()监视的读、写和异常处理的文件描述符集合,numfds的值是需要检查的号码最高的文件描述符加1. timeout参数是一个指向struct timeval类型的指针,它可以使select()在等待timeout时间后若没有文件描述符准备好则返回。

struct timeval

{

int tv_sec; // 秒

int tv_usec; // 微秒

}

设置、清除、判断文件描述符集合:

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) // 判断文件描述符是否被置位

设备驱动中的轮询编程

poll()函数:

unsigned int (*poll)(struct file *flip, struct poll_table *wait);

第一个参数为file结构指针,第二个参数为轮训表指针。这个函数进行一下两项工作:

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

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

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

void poll_wait(struct file *flip, wait_queue_head_t *queue, poll_table *wait);

这个函数不会引起阻塞。poll_wait()函数所做的工作是把当前进程添加到wait参数指定的等待列表(poll_table)中。

poll()函数应该返回设备资源的可获取状态,即POLLIN、POLLOUT、POLLPRI、POLLERR、POLLNVAL等宏的位“或”结果。

poll()模板:

static unsigned int xxx_poll(struct file *filp, 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 |= POLLOUT | POLLWRNORM; // 标示数据可写入

}

...

return mask;

}

用户空间调用select()和poll()接口,设备驱动提供poll()函数。设备驱动的poll()本身不会阻塞,但是poll()和select()系统调用则会阻塞地等待文件描述符集合中的至少一个可访问或超时。

等待队列:

Wait.h (include\linux) 16279 2009/12/3

1.定义

DECLARE_WAIT_QUEUE_HEAD(name):

生成一个等待队列头wait_queue_head_t,名字为name

定义一个变量队列头name并且初始化

#define DECLARE_WAIT_QUEUE_HEAD(name) \

wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)

init_wait(wait)

wait_queue_t wait;定义

init_wait(&wait); 初始化。

让进程休眠:

wait_event(wq, conditio) :

在wq队列上休眠,condition:休眠条件,当为0时候休眠,当为非0时候不休眠

不会被信号中断,不可杀进程

wait_event_timeout(wq, condition, timeout)

wait_event_interruptible(wq, condition)

可以被信号中断。

唤醒函数:

wake_up(wq) 可以 唤醒 以上三种休眠方式

wake_up_interruptible(wq) 唤醒 wait_event_interruptible

wait_event_interruptible_timeout(wq, condition, timeout)

唤醒 wait_event_timeout

linux write引起进程挂起,Linux设备驱动中的阻塞与非阻塞总结相关推荐

  1. linux 查看进程阻塞,linux进程 阻塞和非阻塞操作

    在我们看全功能的 read 和 write 方法的实现之前, 我们触及的最后一点是决定何时使 进程睡眠. 有时实现正确的 unix 语义要求一个操作不阻塞, 即便它不能完全地进行下去. 有时还有调用进 ...

  2. linux非阻塞输入函数,Linux fcntl函数设置阻塞与非阻塞

    转自http://www.cnblogs.com/xuyh/p/3273082.html 用命令F_GETFL和F_SETFL设置文件标志,比如阻塞与非阻塞 F_SETFL     设置给arg描述符 ...

  3. linux设备驱动学习(四)——阻塞与非阻塞I/O

    1.阻塞与非阻塞I/O介绍 阻塞和非阻塞I/O是设备访问的两种不同模式.阻塞操作是指在执行设备操作时,若不能获得资源,则挂起进程直到满足可操作的条件后再进行操作.被挂起的进程进入睡眠状态,被从调度器的 ...

  4. Linux 设备驱动中的 I/O模型(一)—— 阻塞和非阻塞I/O

    在前面学习网络编程时,曾经学过I/O模型 Linux 系统应用编程--网络编程(I/O模型),下面学习一下I/O模型在设备驱动中的应用. 回顾一下在Unix/Linux下共有五种I/O模型,分别是: ...

  5. linux 设备驱动阻塞,深入浅出:Linux设备驱动中的阻塞和非阻塞I/O

    今天写的是Linux设备驱动中的阻塞和非阻塞I/0,何谓阻塞与非阻塞I/O?简单来说就是对I/O操作的两种不同的方式,驱动程序可以灵活的支持用户空间对设备的这两种访问方式. 一.基本概念: 阻塞操作 ...

  6. linux编写驱动后write已杀死_《Linux4.0设备驱动开发详解》笔记--第九章:Linux设备驱动中的异步通知与同步I/O...

    在设备驱动中使用异步通知可以使得对设备的访问可进行时,由驱动主动通知应用程序进行访问.因此,使用无阻塞I/O的应用程序无需轮询设备是否可访问,而阻塞访问也可以被类似"中断"的异步通 ...

  7. Linux设备驱动中的阻塞与非阻塞I/O

    阻塞和非阻塞I/O是设备访问的两种不同模式,驱动程序可以灵活的支持用户空间对设备的这两种访问方式 本例子讲述了这两者的区别 并实现I/O的等待队列机制, 并进行了用户空间的验证 基本概念: 1> ...

  8. Linux驱动(六)设备驱动中的阻塞与非阻塞IO

    我们在Linux学习(二十三)IO模型中了解了LINUX中IO模型,IO模型最简单的可以分为阻塞IO和非阻塞IO.并且学习了一个用如何使用阻塞操作和非阻塞操作.而应用层之所以能实现阻塞操作和非阻塞操作 ...

  9. Linux 设备驱动中的阻塞与非阻塞 I/O

    阻塞操作是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作.被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足.而非阻塞操作的进程在不能进行设备操作时 ...

最新文章

  1. leveldb源码分析:数据查询
  2. 试图执行系统不支持的操作
  3. linux下java写ftp服务器端,在Linux下部署网站(java环境部署)第五章 FTP服务器搭建...
  4. 如何优雅地向导师/老板表示:“上周工作没什么进展”?
  5. [渝粤教育] 西南科技大学 计算机工业控制 在线考试复习资料
  6. 怎么让织梦文章按照权重排序
  7. flash动画设计期末作业_「2019年下学期」第二十五二十六节:期末作品三-吉祥物设计...
  8. webservice 服务器无法处理请求_Message Queue与WebService比较
  9. android locknow,java – Android DevicePolicyManager lockNow()
  10. SSD磁盘测试不达标排查
  11. Linux下动态库(.so)和静态库(.a) 的区别
  12. mysql root dengru_Mysql学习Mysql中文汉字转拼音的实现(每个汉字转换全拼)
  13. PowerDesigner15下载安装
  14. 测试开发—码流、单码流、双码流、多码流
  15. TypeError: Cannot read property ‘id‘ of null
  16. [语音处理] .flac文件转.wav文件
  17. 《土耳其瞭望塔》背后的故事
  18. 实时自动驾驶车辆定位技术都有哪些?(视觉/Lidar/多传感器数据融合)
  19. CCNP证书的含金量和以前考四科的时候相比并没有下降
  20. 牛客网数量关系8道、判断推理8道、智力题8道

热门文章

  1. ORA-00600 kcratr_nab_less_than_odr 问题处理
  2. 用Python实现图片风格迁移,让你的图片更加的高逼格!
  3. 尾气冒黑烟是什么问题_排气管老是冒黑烟是咋回事?原因在此
  4. 车灯线光源的优化设计matlab,基于 Matlab 的车灯线光源优化设计的实施方案
  5. 《小岛经济学》四、最成功的栽赃——通货紧缩
  6. html立方体翻转,jQuery 3D立方体翻转插件
  7. python提取mp3专辑图片
  8. java课程设计成绩管理系统_Java课程设计--学生成绩管理系统
  9. 写在毕业之前-回顾2017,展望2018-
  10. sqlserver替换字段第一位数字