一起学netty(4)io模型的同步、异步、阻塞、非阻塞的概念理解
之前的文章中提到了java中的nio是同步非阻塞的网络io模型,本文就主要说明一下同步、异步、阻塞、非阻塞的概念来帮助理解nio。
io操作
IO分两阶段(一旦拿到数据后就变成了数据操作,不再是IO):
- 1.数据准备阶段
- 2.内核空间复制数据到用户进程缓冲区(用户空间)阶段
在操作系统中,程序运行的空间分为内核空间和用户空间。应用程序都是运行在用户空间的,所以它们能操作的数据也都在用户空间。
阻塞IO和非阻塞IO的区别在于第一步发起IO请求是否会被阻塞:如果阻塞直到完成那么就是传统的阻塞IO,如果不阻塞,那么就是非阻塞IO。
一般来讲,阻塞IO模型、非阻塞IO模型、IO复用模型(select/poll/epoll)、信号驱动IO模型都属于同步IO,因为阶段2是阻塞的(尽管时间很短)。
同步IO和异步IO的区别就在于第二个步骤是否阻塞:IO过程如果阻塞,需要用户空间主动获取数据,期间不能做其它事,则是同步IO,如果不阻塞,而是操作系统帮你做完IO操作再将结果返回给你,那么就是异步IO。
同步和异步IO 阻塞和非阻塞IO的概念
同步和异步IO的概念:
同步是用户线程发起I/O请求后需要等待或者轮询内核I/O操作完成后才能继续执行。
异步是用户线程发起I/O请求后仍需要继续执行,当内核I/O操作完成后会通知用户线程,或者调用用户线程注册的回调函数。
阻塞和非阻塞IO的概念:
阻塞是指I/O操作需要彻底完成后才能返回用户空间。
非阻塞是指I/O操作被调用后立即返回一个状态值,无需等I/O操作彻底完成。
同步与异步(线程间调用)
同步与异步是对应于调用者与被调用者,它们是线程之间的关系,两个线程之间要么是同步的,要么是异步的。
同步操作时,调用者需要等待被调用者返回结果,才会进行下一步操作。而异步则相反,调用者不需要等待被调用者返回调用,即可进行下一步操作,被调用者通常依靠事件、回调等机制来通知调用者结果。
阻塞与非阻塞(线程内调用)
阻塞与非阻塞是对同一个线程来说的,在某个时刻,线程要么处于阻塞,要么处于非阻塞。
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态:阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。
举个栗子
喝茶的故事,出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
同步阻塞:老张把水壶放到火上,立等水开。
老张觉得自己有点傻
同步非阻塞:老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。
老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的噪音。
异步阻塞:老张把响水壶放到火上,立等水开。
老张觉得这样傻等意义不大
异步非阻塞:老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。
老张觉得自己聪明了。