Linux阻塞控制 wait_event与wait_event_interruptible函数详解

最近研究了一下linux驱动对进程的阻塞与非阻塞的控制,感觉linux对进程的控制真的是牛逼,各种进程的状态都会有相应的控制方案来解决,开始慢慢感受到linux的博大精深了。

1、  引入阻塞的必要性

刚开始学习阻塞时一直都会有疑惑,为什么需要引入阻塞,同样是等待信号,将当前线程休眠,那信号量与wait_event这样的阻塞有什么样的区别呢。

down(struct semaphore * sem)

wait_event_interruptible(wq, condition, ret)

我自己总结了一下,主要是由如下几个区别和联系,

a、  进程控制的思想一样,都是通过对信号的控制来实现不同进程之间的控制,区别在于互斥锁之类的控制是直接使用linux进行规范化的信号量sem来操作,而阻塞控制则是通过对自定义的标记符condition来进行控制。

b、  休眠的机制是一样的,都是通过wait_queue来进行任务休眠。

c、  具体实现机制的区别,互斥锁等是通过信号量来控制进程,而信号量是有限资源,从而导致拥有信号量的各个进程是存在竞争关系的;阻塞机制则是通过触发唤醒实现的,这个触发信号是无限的。各个进程不存在竞争关系,只有触发与被触发的关系,而被触发的各个进程之间是平行的。

可以用比赛关系来形象表示这两者的区别:

赛场上进行比赛,每个人必须拿到接力棒才能开始跑,跑的人跑完一圈之后,再将接力棒交给另外的人,另外的人才能开始跑。这是信号量的工作机制,必须拿到信号才能进行进程。而同时进行的进程是有限的。跑的人与没有跑的人之间是互斥的。

进行比赛时,一堆人在准备跑等待发号施令,当鸣枪声想起时就开始跑,跑完之后再等待鸣枪声。这就是阻塞的工作机制,被触发的进程可以无限制,相互之间没有竞争关系,只有触发被触发关系。

2、下面来分析wait_event_interruptible的源代码

#definewait_event_interruptible(wq, condition)

({

int __ret = 0;

if (!(condition))

//第一次执行,如果condition不满足,进入下一步,如果condition满足的话,函数不会进入休眠,直接执行过去,而不是进入休眠后再检测condition,然后再唤醒。

__wait_event_interruptible(wq,condition, __ret);

__ret;

//宏函数返回值,最后一个式子

})

#define__wait_event_interruptible(wq, condition, ret)

do {

DEFINE_WAIT(__wait);

for (;;) {

prepare_to_wait(&wq, &__wait,TASK_INTERRUPTIBLE);

//将当前进程加入到wq这一个等待序列当中,并将进程设置为INTERRUPTIBLE

if (condition)

break;

//如果condition满足直接跳出操作,执行finish_wait,结束等待,而不会进行进程调度

if (!signal_pending(current)) {

//检测当前进程是否有信号处理,返回非0表示

有信号处理,即这里是如果没有信号处理,则进入下一步,

schedule();

//进行进程调度,将当前进程从runqueue中删除,此时该进程在此处休眠,schedule不返回,不再往下执行;只有当wake_up函数将该进程的状态设为可运行时,该进程才能重新进入运行序列,schedule()顺利返回,继续往下执行

continue; }

//直接进入到for (;;)的下一个循环,检测condition是否满足要求,如果满足,跳出for循环,跳到finish_wait,如果不满足,则继续进行进行调度。

ret = -ERESTARTSYS;

break;

}

finish_wait(&wq, &__wait);

//将当前进程从wq等待队列中删除

} while (0)

linux的阻塞waitqueue,Linux阻塞控制 wait_event与wait_event_interruptible函数详解相关推荐

  1. php output详解,PHP输出缓冲控制Output Control系列函数详解,output函数详解

    PHP输出缓冲控制Output Control系列函数详解,output函数详解 概述 以前研究过PHP的输入输出缓冲,不过博客搬家以后,原来文章找不到了,今天看到一篇好文,顺便转载过来. 简介 说到 ...

  2. Linux进程最大socket数,Linux下高并发socket最大连接数所受的各种限制(详解)

    1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每 ...

  3. Linux 文件锁 fcntl 函数详解

    Linux 文件锁 fcntl 函数详解 #include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd); ...

  4. linux内核中send与recv函数详解

    Linux send与recv函数详解 1.简介 #include <sys/socket.h> ssize_t recv(int sockfd, void *buff, size_t n ...

  5. linux send与recv函数详解

    linux send与recv函数详解 1 #include <sys/socket.h> 2 ssize_t recv(int sockfd, void *buff, size_t nb ...

  6. 【Linux系统编程】vfork() 函数详解

    00. 目录 文章目录 00. 目录 01. vfork函数 02. fork和vfork区别 03. 父子进程地址空间 04. 附录 01. vfork函数 函数分析 #include <sy ...

  7. linux Socket send与recv函数详解

    转自:http://www.cnblogs.com/blankqdb/archive/2012/08/30/2663859.html linux send与recv函数详解 1 #include &l ...

  8. linux中recvfrom读取速度,Linux系统调用-- recv/recvfrom 函数详解

    Linux系统调用-- recv/recvfrom函数详解 功能描述: 从套接字上接收一个消息.对于recvfrom,可同时应用于面向连接的和无连接的套接字.recv一般只用在面向连接的套接字,几乎等 ...

  9. linux下wait函数,Linux wait函数详解

    wait和waitpid出现的原因 SIGCHLD --当子进程退出的时候,内核会向父进程SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止) --子进程退出时,内核将 ...

最新文章

  1. 一个流畅的iOS图表框架PNChart
  2. 孕期骨质疏松危害大 及时补钙很重要
  3. 重新封装了一下NODE-MONGO 使其成为一个独立的服务.可以直接通过get/post来操作
  4. ARM汇编 beq和bne
  5. python sql 日期查询_Python--flask使用 SQLAlchemy查询数据库最近时间段或之前的数据...
  6. C语言 枚举,进制,原码,反码,补码,移码,结构体
  7. springboot环境搭建及入门必知
  8. HDU2098 分拆素数和【筛选法】
  9. 肉肉好走,愿你在异界依旧快乐活泼
  10. [FPGA] 三位四选一数据选择器
  11. 12.4 正项数项级数收敛的充要条件及比较判别法
  12. [bzoj2434][AC自动机][树状数组]阿狸的打字机
  13. 两种特殊卷积:转置卷积和空洞卷积
  14. 【解局】瑞幸向上,盒马向下
  15. 八进制换算成二进制、十进制、十六进制
  16. php为网页更改颜色,php如何设置网页颜色?
  17. PTA 哈夫曼树与哈夫曼编码
  18. STP分析--保险公司客户分类分析(采用SPSS进行分析)
  19. 哪吒汽车的技术发布会都发布了什么?纯干货抢先看
  20. C#得到10000以内素数

热门文章

  1. 弧形背景html,JS实现带圆弧背景渐变效果的导航菜单代码
  2. vba mysql odbc_使用VBA+ODBC+MySQL实现Excel网络版
  3. 3MIN干完一周的工作量?快来看看应该如何部署 Kubernetes!
  4. 宜家如何利用低代码平台提升员工效率,提高数据价值
  5. 每日一皮:进来说说昨天你是怎么过的?
  6. 每日一皮:产品经理的黑化,你听过几个?
  7. 每日一皮:晕,程序重新请求一下,结果还不一样了!
  8. 用c#算成绩的总和_C# 基础知识系列- 6 Lambda表达式和Linq简单介绍
  9. RGBD 转换成点云 open3d
  10. 分割2021PanopticFCN