5种I/O模型

阻塞

在这里插入图片描述

非阻塞

非阻塞I/O,如果I/O事件没有就绪就会立刻返回, 可以根据返回值和 errno 区分各种情况, 返回后我们可以去做其他事. 由于不阻塞, 所以为了完成读/写, 通常循环调用I/O函数, 直到事件发生后, 才去拷贝(从内核的读缓冲区拷贝到用户态或者用户态拷贝进内核的写缓冲区), 拷贝完成后返回
在这里插入图片描述

I/O复用

Linux使用select, poll, epoll函数实现I/O复用模型,这些函数也会使进程阻塞,但是和阻塞IO所不同的是 这些函数可以同时阻塞多个IO操作。而且可以同时对多个读操作、写操作的IO函数进行检测。直到有文件描述符发生了我们检测的读/写事件时,才真正去读/写;
I/O复用并不是提高并发的, 而是在单进程/线程环境下可以同时阻塞并且检测多个I/O
在这里插入图片描述

信号驱动

注册某个信号捕捉函数, 进程可以继续运行, 等到I/O事件就绪后, 进程收到一个信号, 并且去执行预先设置的信号处理函数去处理I/O事件;
因此, 在第一个阶段是异步的, 但真正读/写这个操作仍然是同步的. 但比非阻塞I/O好的一点是: 它提供了消息通知机制, 不需要用户进程不断轮循检查, 减少了系统API的调用次数, 使CPU减少了很多无用的空转
在这里插入图片描述

异步

以读为例, Linux提供了 aio_read 函数, 调用它会告诉内核描述符缓冲区的位置、存到哪, 及通知的方式,然后立即返回,当内核将数据拷贝到缓冲区后,再以某种方式通知应用程序, 这才是真正的异步.
在这里插入图片描述

struct aiocb { // 存了预先告知内核的信息
	int aio_fildes;       /* File desriptor.  */  
	int aio_lio_opcode;       /* Operation to be performed.  */  
	int aio_reqprio;      /* Request priority offset.  */  
	volatile void *aio_buf;   /* Location of buffer.  */  
	size_t aio_nbytes;        /* Length of transfer.  */  
	struct sigevent aio_sigevent; /* Signal number and value.  */
	
	/* Internal members.  */  
	struct aiocb *__next_prio;  
	int __abs_prio;  
	int __policy;  
	int __error_code;  
	__ssize_t __return_value;
	
	#ifndef __USE_FILE_OFFSET64  
	__off_t aio_offset;       /* File offset.  */  
	char __pad[sizeof (__off64_t) - sizeof (__off_t)]; 
	#else  
	__off64_t aio_offset;     /* File offset.  */ 
	#endif  
	char __glibc_reserved[32]; 
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值