Linux设备驱动中的阻塞和非阻塞I/0,简单来说就是对I/O操作的两种不同的方式,驱动程序可以灵活的支持用户空间对设备的这两种访问方式。 非阻塞应用程序通常使用select系统调用查询是否可以对设备进行无阻塞的访问最终会引发设备驱动中 poll 函数执行。 =1); //串口上没有输入则返回,所以循环读取 printf("%c/n",buf); 阻塞操作常常用等待队列来实现,而非阻塞操作用轮询的方式来实现。 非阻塞I/O的操作在应用层通常会用到select()和poll()系统调用查询是否可对设备进行无阻塞访问。select()和poll()系统调用最终会引发设备驱动中的poll()函数被调用。 return mask; } 三、总结 阻塞与非阻塞操作: 定义并初始化等待对列头; 定义并初始化等待队列; 把等待队列添加到等待队列头 设置进程状态(TASK_INTERRUPTIBLE(可以被信号打断
大家如果感兴趣,微信搜索「我是阿沐」关注我这枚有点神经但乐观的程序员~ 2 什么是阻塞、非阻塞、同步、异步? “老公我之前看你天天看操作系统的书的目录有阻塞和非阻塞,是个啥子意思嘛? 「我向来经受不住女生撒娇的」 image.png “从上面图形能看出来什么嘛?可以知道整体的流程是什么样子嘛?”,我对着女票问到 “老公,我看到了,看出来了”,女票兴奋激动的说道。 一个是请求一直处于阻塞状态,用户什么都不能做;一个是用户在请求过程中可以做其他的,然后再等待结果。 最后总结 阻塞/非阻塞:主要是看应用程序等待消息通知的状态来看。阻塞当前线程被挂起,线程什么事情都不能做,只能等待有结果返回才能继续做下一件事情。 这就是说为什么很多并发情况下,大家选择异步去处理业务逻辑。 这篇文章主要是讲下同步、异步、阻塞、非阻塞、并发、并行的概念性,并且通过实际的画图来解说他们到底是怎样的一种情况。
提供包括云服务器,云数据库在内的90+款云计算产品。打造一站式的云产品试用服务,助力开发者和企业零门槛上云。
大部分高性能网络框架采用的是非阻塞模式。笔者这次就从linux源码的角度来阐述socket阻塞(block)和非阻塞(non_block)的区别。 一个TCP非阻塞client端简单的例子 如果我们要产生一个非阻塞的socket,在C语言中如下代码所示: // 创建socket int sock_fd = socket(AF_INET, SOCK_STREAM \非阻塞状态 我们用fcntl修改socket的阻塞\非阻塞状态。 timeo) { copied = -EAGAIN; break; } // 这边如果堵到了期望的数据,继续,否则当前进程阻塞在sk_wait_data上 if (copied 如下图所示: 阻塞后什么时候恢复运行呢 情况1:有对应的网络数据到来 首先我们看下网络分组到来的内核路径,网卡发起中断后调用netif_rx将事件挂入CPU的等待队列,并唤起软中断(soft_irq
这篇博客将介绍Node.js的阻塞(Blocking)与非阻塞(Non-Blocking)。我会提到Event Loop与libuv,但是不了解它们也不会影响阅读。 阻塞(Blocking) 阻塞指的是一部分Node.js代码需要等到一些非Node.js代码执行完成之后才能继续执行。这是因为当阻塞发生时,Event Loop无法继续执行。 对于Node.js来说,由于CPU密集的操作导致代码性能很差时,不能称为阻塞。当需要等待非Node.js代码执行时,才能称为阻塞。 Node.js中依赖于libuv的同步方法(以Sync结尾)导致阻塞,是最常见的情况。当然,一些不依赖于libuv的原生Node.js方法有些也能导致阻塞。 其中一些方法也有对应的阻塞版本,它们的函数名以Sync结尾,例如fs.readFileSync。 代码示例 阻塞的方法是同步执行的,而非阻塞的方法是异步执行。
从linux源码看socket的阻塞和非阻塞 笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情。 大部分高性能网络框架采用的是非阻塞模式。 笔者这次就从linux源码的角度来阐述socket阻塞(block)和非阻塞(non_block)的区别。 本文源码均来自采用Linux-2.6.24内核版本。 一个TCP非阻塞client端简单的例子 如果我们要产生一个非阻塞的socket,在C语言中如下代码所示: // 创建socket int sock_fd = socket(AF_INET, SOCK_STREAM \非阻塞状态 我们用fcntl修改socket的阻塞\非阻塞状态。 阻塞后什么时候恢复运行呢 情况1:有对应的网络数据到来 首先我们看下网络分组到来的内核路径,网卡发起中断后调用netif_rx将事件挂入CPU的等待队列,并唤起软中断(soft_irq),再通过linux
还是拿我们上一篇中提到的排队买奶茶这个例子,看看为什么说是「同步」+「阻塞」。 上图中,几次阻塞之间空白区域就可以用于做其它事,所以是「非阻塞」的。 异步与阻塞/非阻塞 上一篇文章中的「异步」例子就是一个「非阻塞」的例子,我们来看看为什么。 其实你仔细想一下就会发现,很多知名的框架,都是「同步」+「非阻塞」的,为什么呢?因为你可以继续像「同步」一样编写代码,但是可以享受到类似「异步」所能带来的更好的性能,何乐而不为? 比如大名鼎鼎的linux中的io复用模型poll/select/epoll,本质上都是「同步」+「非阻塞」的。还有知名网络通信框架Netty。 之所以大家会有错觉,认为「异步」=「非阻塞」,其实也不是没有道理。为什么呢?因为我在脑海中搜寻来一番,的确没想到有什么知名的框架/设计是使用「异步」+「阻塞」来实现的。
试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。 如果Queue已经满了,put方法会被阻塞直到有空间可用;如果Queue是空的,那么take方法会被阻塞,直到有元素可用。 阻塞队列简化了消费者的编码,因为take会保持阻塞直到可用数据出现。如果生产者不能足够快地产生工作,让消费者忙碌起来,那么消费者只能一直等待,直到有工作可做。 同时,put方法的阻塞特性也大大地简化了生产者的编码;如果使用一个有界队列,那么当队列充满的时候,生产者就会阻塞,暂不能生成更多的工作,从而给消费者时间来赶进进度。 一个线程的失败或挂起不应该影响其他线程的失败或挂起,这样的算法成为非阻塞(nonblocking)算法;如果算法的每一个步骤中都有一些线程能够继续执行,那么这样的算法称为锁自由(lock-free)算法
哦,那是阻塞的还是非阻塞的呢? ? 额、阻塞吧。 ? 恭喜你,选择了一种最慢的方式。 ? 什么鬼嘛,你给我绕懵了,给我讲讲这都是啥意思。 ? 什么是同步和异步 说到烧水,我们都是通过热水壶来烧水的。在很久之前,科技还没有这么发达的时候,如果我们要烧水,需要把水壶放到火炉上,我们通过观察水壶内的水的沸腾程度来判断水有没有烧开。 原来是这样啊,那阻塞和非阻塞呢? ? 别急,听我慢慢和你说。 ? 什么是阻塞和非阻塞 还是那个烧水的例子,当你把水放到水壶里面,按下开关后,你可以坐在水壶前面,别的事情什么都不做,一直等着水烧好。 对于你来说,坐在水壶前面等就是阻塞的,去客厅看电视等着水开就是非阻塞的。 阻塞请求,A调用B,A一直等着B的返回,别的事情什么也不干。 非阻塞请求,A调用B,A不用一直等着B的返回,先去忙别的事情了。 所以说,阻塞非阻塞最大的区别就是在被调用方返回结果之前的这段时间内,调用方是否一直等待。阻塞指的是调用方一直等待别的事情什么都不做。
今天来上一堂语文课,大家跟我念:兹z武u,阻zu。丝s饿e,塞se。看还有哪个家伙读成阻zu塞sai的,还有谁不会念? 你还真的点开链接啦? 今天真的是一趟语文课,就教会大家正确念这两个字的姿势,看: 兹z武u,阻zu。 丝s饿e,塞se。 阻塞。 好吧,再来一点营养。阻塞是啥意思呢? 就是水管堵住了!扭开水龙头没有水出来。 这个道理跟Linux下读取慢速设备(主要指管道和套接字)数据的情形非常相似,例如当我们在读取一个管道时,如果管道里面没有数据,那么我们什么都读不出来,于是就进入了所谓的“阻塞”状态了,说白了阻塞就是使得当前进程或者线程睡眠了的意思 那么再进一步,什么时候会阻塞呢?下面的表格简单描述了这些清空: ? 其中,读者指的是对管道文件拥有读权限的进程或线程(注意不是正在读),写者指的是对管道文件拥有写权限的进程或线程(注意不是正在写)。 除此之外,其实open()函数也会发生阻塞,比如用只读或者只写open一个管道文件的时候。因为一根只有出口或者只有入口的水管,是无法使用的呀!其实就是生活常识。嘿嘿!
为什么我们不要在nodejs中阻塞event loop 简介 我们知道event loop是nodejs中事件处理的基础,event loop中主要运行的初始化和callback事件。 如果这两种线程执行callback花费了太多的时间,那么我们就可以认为这两个线程被阻塞了。 线程阻塞第一方面会影响程序的性能,因为某些线程被阻塞,就会导致系统资源的占用。 阻塞event loop 因为nodejs中的线程有限,如果某个线程被阻塞,就可能会影响到整个应用程序的执行,所以我们在程序设计的过程中,一定要小心的考虑event loop和worker pool,避免阻塞他们 event loop主要关注的是用户的连接和响应用户的请求,如果event loop被阻塞,那么用户的请求将会得不到及时响应。 REDOS正则表达式DOS攻击 正则表达式有什么问题呢?正则表达式有一个悲观回溯的问题。 什么是悲观回溯呢? 我们举个例子,假如大家对正则表达式已经很熟悉了。
本文试图理清楚几种IO模型的根本性区别,同时分析了为什么在Linux网络编程中最好要用非阻塞式IO? 这些名词非常容易混淆,为什么一个IO会有两个限定词:同步和阻塞?同步和阻塞分别代表什么意思? 所以有的时候,习惯了操作磁盘IO的开发者会无法理解同步阻塞IO的工作过程,无法理解为什么read函数不会返回。 关于磁盘IO与同步非阻塞的讨论,在知乎上有一篇帖子为什么书上说同步非阻塞io在对磁盘io上不起作用? 讨论了这个问题。 为什么在Linux网络编程中最好要用非阻塞式IO? 上文说到,在linux网络编程中,如果使用阻塞式的IO,假如某个fd长期不可读,那么一个线程相应将会被长期阻塞,那么线程资源就会被白白浪费。
对比概念 阻塞与非阻塞 数据就绪前要不要等待? 阻塞:没有数据传过来时,读会阻塞直到有数据;缓冲区满时,写操作也会阻塞 非阻塞:直接返回 同步与异步 数据就绪后,数据操作谁完成? 为什么废除阻塞I/0 (BIO/OIO) ? 连接数高的情况下:阻塞 -> 耗资源、效率低。 阻塞意味着等待,等待就会一直占用该线程,当连接数高时,大多线程又在等待,就会耗尽系统的线程资源。 为什么删掉已经做好的AIO支持? 为什么 Netty 支持多种实现? 让我们再看一次表格 ?
1.2 对比概念 阻塞与非阻塞 数据就绪前要不要等待? 阻塞 没有数据传过来时,读会阻塞直到有数据;缓冲区满时,写操作也会阻塞 非阻塞 直接返回 同步与异步 数据就绪后,数据操作谁完成? 为什么废除阻塞I/0 (BIO/OIO) ? 连接数高的情况下:阻塞 -> 耗资源、效率低。 阻塞意味着等待,等待就会一直占用该线程,当连接数高时,大多线程又在等待,就会耗尽系统的线程资源。 为什么删掉已经做好的AIO支持? 为什么 Netty 支持多种实现? ?
,异步表现在于馒头好了后,阿梅会主动告诉研究僧 总结一下大概意思就是: [ 阻塞 ]和[ 非阻塞 ]在于等馒头的时候,研究僧在干什么 [ 同步 ]和[ 异步 ]在于是研究僧自己主动获取馒头状态,还是被动由阿梅通知 这里的异步在说什么?是在说业务流的逻辑流程。我坚信你们的PHP代码在把消息放入消息队列的时候用的函数方法都是同步且阻塞,不可能是异步,所以这里说异步不可能在是在说IO复用、AIO。 场景三:Nginx是基于事件监听的异步非阻塞高性能服务器,这里的异步是在说什么? 既然在Linux下Nginx事件是基于epoll实现的,然而上面又说了epoll这样的IO复用属于同步,那这里为什么会说[ 异步 ]非阻塞? 所以如果是你自己想研究异步非阻塞,你要搞清楚此处异步是指什么;和他人在工作中提到了异步,都要搞明白具体的场景和立场是什么,两个人在一个频道上才能扯明白。
listenfd 为什么一定要设置成非阻塞的,我在另外一篇文章中写的很清楚: 高性能网络通信库中为何要将侦听 socket 设置成非阻塞的? 当然,我自己也出版了一本书《C++ 服务器开发精髓》: 在 2021 年写一本 C++ 图书是一种什么体验? 主机字节序 387 4.16.2 网络字节序 388 4.16.3 操作系统提供的字节转换函数汇总 389 4.17 域名解析API介绍 390 推荐阅读 在 2021 年写一本 C++ 图书是一种什么体验 写给想去字节写 Go 的你 《C++服务器开发精髓》签名版请签收 为什么你的简历没人看? 大厂,那高高的围墙 来看一看两道大厂的场景题 为什么你字节跳动的面试没下文了? 工作 3 万,副业 5 万 写代码太苦了,我决定改行送外卖去了 我们说 TCP 是流式协议意味着什么? 有哪些不错的 Golang 开源项目?
考虑到 write system call 被阻塞可长达几百 ms,我想我能抓出当前进程的内核栈来看一下 write system call 此时被阻塞在什么位置。 ,还要查它会什么会阻塞在这里。 不算结论的结论 ---- 寻找写锁 知道了 write system call 阻塞在获取读锁,那么一定是内核里有哪些地方持有了写锁。 , 追着 OenHan 问了几次也没有什么结论:Linux内核写文件流程。 linux 真的是博大精深,希望有一天我也能对此有所贡献。 关于本文有什么疑问可以在下面留言交流,如果您觉得本文对您有帮助,欢迎关注我的 微博 或 GitHub 。
腾讯服务器操作系统(TencentOS Server,TS)是腾讯云推出的Linux操作系统,它旨在为云上运行的应用程序提供稳定、安全和高性能的执行环境。它可以运行在腾讯云CVM全规格实例上,包括黑石2.0服务器。
扫码关注云+社区
领取腾讯云代金券