①内核空间(kernel-Space):内核模块运行在内核空间,对应的进程处于内核态;
②用户空间(User-Space):用户程序运行在用户空间,对应的进程处于用户态。
内核态和用户态是操作系统的两种运行状态。
1.1、内核态操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内核空间,也有访问底层硬件设备的权限。内核空间总是驻留在内存中,它是为操作系统的内核保留的。应用程序是不允许直接在内核空间域进行读写,也是不允许直接调用内核代码定义的函数。
1.4、IO底层
设置缓冲区的目的为:减少频繁地与设备之间的物理交换。
有了内核缓冲区,操作系统会对内核缓冲区进行监控,等待缓冲区达到一定数量时,再进行IO设备的中断处理,集中执行物理设备的实际IO操作,通过这种机制来提升系统的性能。至于具体在什么时候执行系统中断(包括读中断、写中断),则由系统的内核来决定,应用程序不需要关心这个问题。
上层应用程序使用sys_read系统调用时,仅仅是吧数据从内核缓冲区复制到了进程缓冲区;
而在使用sys_write系统调用时,仅仅是把数据从进程缓冲区复制到了内核缓冲区。
IO的基本概念
1、阻塞IO和非阻塞IO网卡同步数据到内核缓冲区,如果内核缓冲区中的数据未准备好,用户进程发起read操作,阻塞则会一直等待内存缓冲区数据完整后再解除阻塞,而非阻塞则会立即返回不会等待,注意,内核缓冲区与用户缓冲区之间的读写操作肯定是阻塞的。
2、同步和异步同步:调用者主动发送请求,调用者主动等待这个结果返回,一旦调用就必须有返回值;异步:调用发出后直接返回,所以没有返回结果。被调用者处理完成后通过回调、通知等机制来通知调用者。
我觉得它不属于一种单独的IO模型,只是IO中一种提高用户态与内核态交换数据的效率,原本是每次交换只交换一个,通过多路复用后,加入了一个文件描述符fd,一次交换可以交换多个IO的状态数据。
select使用了一个fd_set集合来保存需要监控的文件描述符,并提供了select()函数来检查这些文件描述符的状态。当调用select()函数时,内核会遍历这个fd_set集合,检查每个文件描述符的状态是否就绪。如果某个文件描述符就绪,select()函数就会返回,否则会阻塞程序直到有文件描述符就绪或超时。
监视的文件描述符数量有最大限制,通常为1024,增加数量会降低性能。
3.2、poll
3.3、epollepoll可以理解为eventpoll,它是一种事件驱动的I/O模型,可以用来替代传统的select和poll模型。epoll的优势在于它可以同时处理大量的文件描述符,而且不会随着文件描述符数量的增加而降低效率。(也即不需要遍历)
epoll的实现机制是通过内核与用户空间共享一个事件表,这个事件表中存放着所有需要监控的文件描述符以及它们的状态,当文件描述符的状态发生变化时,内核会将这个事件通知给用户空间,用户空间再根据事件类型进行相应的处理。
epoll使用了一个事件表(eventtable)来保存需要监控的文件描述符和相应的事件类型,并提供了epoll_ctl()函数来向事件表中添加、修改或删除文件描述符。与select和poll不同的是,epoll的设计更加高效,它使用了内核中的事件通知机制,可以避免遍历文件描述符集合,当文件描述符的状态发生变化时,内核会立即通知应用程序。这样可以避免遍历文件描述符集合,减少了不必要的CPU消耗,从而提高了效率。当调用epoll_wait()函数时,它会返回一个包含已就绪文件描述符的列表,并且它只返回那些真的有事件发生的文件描述符。这意味着它避免了遍历整个事件表,直接返回你感兴趣的文件描述符。
外卖点单–下完单出餐后由快递送过来,你在这期间可以去干别的事情