IO
IO
IO 用户进程-调用系统调用-内核 内核-准备数据(等待数据) 内核-数据拷贝 内核-数据返回-用户
阻塞IO:内核数据未准备好时阻塞用户进程 直到内核返回数据
非阻塞IO:内核数据未准备好返回给用户进程一个error 用户进程轮询数据 直到内核数据准备完成返回OK
有个阻塞点 内核拷贝数据时 用户进程被阻塞
IO多路复用(event driven IO (事件驱动IO)):select接管多个用户进程轮询IO的任务 用户调用select后进入阻塞 等select返回
内核监视所有select负责的socket
与阻塞io不同点:用户线程阻塞在select 阻塞io阻塞在socket io处
select优势:同时处理多个连接 若连接数较少 性能可能不比多线程+阻塞io好(阻塞io系统调用少一个)
异步IO:用户发送给内核请求后可以去做别的事情,不必等数据,内核在数据准备好(已拷贝)后通知用户进程
条件编译
条件编译1
小细节 宏定义不加;
宏定义可用于小函数 省栈(避免频繁入栈出栈 省cpu)性能优 不过不利于调试 可用inline替代
ifndef 防止重复包含头文件的宏
defined 可用于在一条判断语句中声明多个判别条件;#ifdef和#ifndef则仅支持判断一个宏是否定义
#elif不仅仅是检查后面的宏有没有定义,还会检查值。但是#ifdef就只是检查后面的宏是否定义,而不管值为多少
#ifdef 可用于debug打印
条件编译2
io:面向流的方式处理数据(单个的字节,字符的移动,流的一次操作一次只能产生或者消费一个字节或者字符即使有缓冲,也需要程序员自己填充和提取缓冲区内容)
nio:面向块的方式处理数据(数据块的移动,一次操作产生或者消费一个数据块,将最耗时的 I/O 操作–填充和提取缓冲区内容操作转移回操作系统)NIO包引入了四个关键的抽象数据类型
- Buffer:它是包含数据且用于读写的线形表结构(字节数组)。其中还提供了一个特殊类用于内存映射文件的I/O操作。一个 Buffer 实质上是一个容器对象。发送给一个通道的所有对象都必须首先放到缓冲区中;同样地,从通道中读取的任何数据都要读到缓冲区中
- Charset:它提供Unicode字符串影射到字节序列以及逆影射的操作(编码及解码器)
- Channels:通道是对原 I/O 包中的流的模拟。到任何目的地(或来自任何地方)的所有数据都必须通过一个 Channel 对象。包含socket,file和pipe三种管道,它实际上是双向交流的通道(与流的不同之处在)
- Selector:它将多元异步I/O操作集中到一个或多个线程中
•读取文件操作:(1) 从 FileInputStream 获取Channel, (2) 创建Buffer, (3) 将数据从 Channel 读到 Buffer中.
•写入文件操作:(1)从 FileOutputStream 获取Channel, (2)创建Buffer, (3)将数据从 Channel 写到 Buffer中.
•重设缓冲区操作:在从输入通道读入缓冲区之前,我们调用 clear() 方法。同样,在将缓冲区写入输出通道之前,我们调用 flip() 方法
•检查状态操作: read() 方法返回 -1 是判断文件读取完成的标志
•注意:不需要告诉通道要写入多数据。缓冲区的内部统计机制会跟踪它包含多少数据以及还有多少数据要写入
————————————————
版权声明:本文为CSDN博主「菜鸟腾飞」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/drdongshiye/article/details/78521733
出处
传统socket IO:
一个线程管一个连接,线程读不到数据就阻塞,在io阻塞时 线程挂起 造成资源浪费(线程自己的栈内存 cpu线程切换消耗)
NIO:
线程读不到数据返回0 线程不会阻塞
客户端创建连接时 将连接注册到selector
线程池
cpp线程池
epoll复杂度
epoll原理相关
双向链表+红黑数
红黑树存注册监控的fd
双向链表存就绪fd
收到fd数据 中断 将节点加入链表 epoll_wait收到消息 将链表节点数据写入内存 清链表
要再看
计划
NIO没看完 继续学NIO
用一下select poll epoll
看项目
设计模式
linux命令
看看文件相关
ningx
docker
redis
mongodb
reactor
线程池 细节要看 原理之类的 有些没看懂的变量函数 涉及锁 cond是啥?
锁
内存池