当前位置: 首页 > news >正文

体检中心网站建设方案梅兰商贸网站开发设计

体检中心网站建设方案,梅兰商贸网站开发设计,社区网站建设难点,建设银行网站字体聊聊常见的IO模型 BIO/NIO/AIO/DIO、IO多路复用等IO模型 文章目录 一、前言1. 什么是IO模型2. 为什么需要IO模型 二、常见的IO模型1. 同步阻塞IO#xff08;Blocking IO#xff0c;BIO#xff09;2. 同步非阻塞IO#xff08;Non-blocking IO#xff0c;NIO#xff09;3.…聊聊常见的IO模型 BIO/NIO/AIO/DIO、IO多路复用等IO模型 文章目录 一、前言1. 什么是IO模型2. 为什么需要IO模型 二、常见的IO模型1. 同步阻塞IOBlocking IOBIO2. 同步非阻塞IONon-blocking IONIO3. 异步非阻塞IOAsynchronous IOAIO3.1. Linux AIO3.2. 我们用C写一个简单的示例3.3. 异步通知的实现方式3.3.1. 信号Signal3.3.2. 完成端口Completion Port3.3.3. 事件驱动Event-driven3.3.4. 回调函数Callback 4. 直接内存IODirect IODIO 3. IO多路复用3.1. 多路复用的概念和原理3.2. select模型3.3. poll模型从操作系统的角度来看poll模型的优缺点 3.4. epoll模型3.4.1. 工作原理3.4.2. 使用方法3.4.3. 优缺点 3.5. kqueue模型3.6. IOCP模型3.6.1. IOCP的主要组成部分3.6.2. IOCP模型的工作流程 3.7. 优缺点比较 参考文档 一、前言 常见的I/O模型包括阻塞I/OBlocking I/OBIO、非阻塞I/ONon-blocking I/ONIO、异步I/OAsynchronous I/OAIO、直接I/ODirect I/ODIO以及I/O多路复用I/O Multiplexing等。每种I/O模型都有其特点和适用场景我们今天总结一下聊聊常见IO模型的一些知识虽然不能学以致用但也可以知其然知其所以然。 本文参考 《Boost application performance using asynchronous I/O》及图片来源自本文 https://developer.ibm.com/articles/l-async/https://notes.shichao.io/unp/ch6/ 1. 什么是IO模型 I/OInput/Output模型是指计算机系统中用于处理输入和输出操作的一种模式或范式。它描述了数据在计算机系统中的传输和处理方式。 在计算机系统中输入和输出操作通常涉及与外部设备如硬盘、网络、键盘、显示器等的数据交互。I/O模型定义了如何进行这种数据交互以及程序如何与输入和输出设备进行通信。 常见的I/O模型包括以下几种 阻塞式I/O模型Blocking I/O应用程序在进行I/O操作时会被阻塞直到操作完成。在进行阻塞I/O时应用程序会一直等待直到数据从设备中读取完毕或数据写入到设备中。 非阻塞式I/O模型Non-blocking I/O应用程序进行I/O操作时如果设备上没有数据可读取或无法立即写入数据则应用程序会立即返回并继续执行其他任务而不会等待操作完成。 I/O复用模型I/O Multiplexing通过使用I/O复用机制如select、poll、epoll等应用程序可以同时监视多个I/O操作并在有数据可读写时进行处理从而避免了阻塞。这种模型适用于需要同时处理多个I/O通道的情况。 信号驱动式I/O模型Signal-driven I/O应用程序通过注册信号处理函数在数据就绪时接收操作系统发出的信号然后进行相应的I/O操作。 异步I/O模型Asynchronous I/O应用程序发起I/O操作后可以继续执行其他任务而无需等待I/O操作完成。当I/O操作完成时系统会通知应用程序然后应用程序可以处理已完成的I/O操作。 不同的I/O模型适用于不同的应用场景和需求。选择适合的I/O模型可以提高系统的效率和性能。 2. 为什么需要IO模型 在计算机系统中IO操作是相对较慢的而应用程序通常需要频繁进行IO操作。不同的IO模型可以提供不同的处理方式以满足不同的需求。选择适合的I/O模型可以提高系统的性能、并发处理能力和用户体验使系统能够高效地处理输入和输出操作。 I/O模型是计算机系统中处理输入和输出操作的一种模式它的存在有以下几个重要原因 高效利用资源 I/O操作通常涉及与外部设备的数据交互而这些设备的访问速度相对较慢。使用合适的I/O模型可以充分利用系统资源避免浪费CPU时间等待I/O操作完成。 提高系统吞吐量 通过合理选择I/O模型可以使系统在等待I/O操作完成时能够处理其他任务从而提高系统的并发处理能力和吞吐量。 支持多任务处理 I/O模型使得应用程序能够同时处理多个I/O通道可以在等待某个I/O操作完成时处理其他I/O操作提高系统的并发性能。 响应性和交互性 通过使用非阻塞I/O模型或异步I/O模型应用程序可以在I/O操作进行的同时继续执行其他任务从而提高系统的响应性和用户体验。 二、常见的IO模型 1. 同步阻塞IOBlocking IOBIO 同步阻塞I/OBlocking I/OBIO是一种基本的I/O模型也是最常见的一种。 在同步阻塞I/O模型中当应用程序发起输入或输出操作时它会被阻塞即暂停执行直到操作完成。在进行I/O操作期间应用程序无法执行其他任务必须等待数据的读取或写入完成才能继续执行后续代码。 同步阻塞I/O模型的基本工作流程 1. 应用程序发起一个I/O操作如读取文件、发送网络请求等。 2. 操作系统内核接收到应用程序的请求将控制权交给设备驱动程序。 3. 设备驱动程序开始执行I/O操作它会将请求发送给设备如硬盘、网络接口等。 4. 设备开始进行读取或写入操作这个过程可能需要一定的时间。 5. 在数据操作完成后设备驱动程序将数据传递给操作系统内核。 6. 操作系统内核将数据传递给应用程序并解除应用程序的阻塞状态。 7. 应用程序继续执行后续代码处理接收到的数据。 同步阻塞I/O模型的主要特点是简单易理解但它的缺点是效率较低。当应用程序发起I/O操作时它必须等待操作完成这会导致应用程序的执行被阻塞无法充分利用CPU资源。特别是在高并发环境下同步阻塞I/O模型可能会导致系统性能下降因为一个阻塞的I/O操作可能会阻塞其他任务的执行。 2. 同步非阻塞IONon-blocking IONIO 同步非阻塞I/ONon-blocking I/ONIO是一种相对于同步阻塞I/O的改进模型它提供了一种更高效的I/O处理方式。 在同步非阻塞I/O模型中当应用程序发起输入或输出操作时它不会被阻塞等待操作完成而是立即返回。应用程序可以继续执行其他任务而不必等待I/O操作的完成。 EWOULDBLOCK或EAGAIN是一些常见的错误码用于表示在非阻塞I/O操作中操作无法立即完成的情况。 EWOULDBLOCK 表示操作将会阻塞。当应用程序以非阻塞方式调用I/O操作时如果操作无法立即完成而需要等待操作系统会返回EWOULDBLOCK错误码。这个错误码提示应用程序当前无法进行操作但并不表示出现了错误。 EAGAIN 表示暂时无法完成操作。类似于EWOULDBLOCKEAGAIN也是在非阻塞I/O操作中表示操作无法立即完成的错误码。它通常用于某些系统或网络资源已经耗尽暂时无法满足请求的情况。 同步非阻塞I/O模型的基本工作流程 应用程序发起一个I/O操作。 如果操作可以立即完成无需等待操作系统内核将数据传递给应用程序并应用程序继续执行后续代码。 如果操作无法立即完成需要等待操作系统内核将返回一个错误码例如EWOULDBLOCK或EAGAIN通知应用程序操作当前无法完成。 4. 应用程序可以通过轮询或其他方式不断查询操作的状态以确定何时可以继续进行操作。 这个是为什么叫做同步非阻塞的原因了 当操作完成后操作系统内核将数据传递给应用程序并应用程序继续执行后续代码。 同步非阻塞I/O模型的主要特点是应用程序不会被阻塞可以继续执行其他任务从而提高系统的并发性能。相比于同步阻塞I/O模型它允许应用程序在等待I/O操作完成时处理其他任务而不会浪费CPU时间。 然而同步非阻塞I/O模型需要应用程序主动查询操作的状态这可能涉及轮询或循环等机制会增加编程复杂性。此外如果应用程序频繁地查询操作的状态可能会导致CPU资源的浪费。为了解决这些问题后续出现了更高级的I/O模型如I/O复用模型、信号驱动式I/O模型和异步I/O模型它们提供了更优雅和高效的方式来处理I/O操作。 3. 异步非阻塞IOAsynchronous IOAIO 异步非阻塞I/OAsynchronous I/OAIO是一种高级的I/O模型与同步阻塞I/O和同步非阻塞I/O有所不同。 在异步非阻塞I/O模型中应用程序发起I/O操作后可以立即返回并继续执行其他任务而不需要等待操作完成或查询操作状态。当I/O操作完成时操作系统会通知应用程序应用程序可以通过回调函数或其他方式处理已完成的I/O操作。 异步非阻塞I/O模型的基本工作流程 应用程序发起一个异步I/O操作并指定一个回调函数。 操作系统内核接收到应用程序的请求并开始执行I/O操作。 应用程序继续执行其他任务而不需要等待操作完成。 当I/O操作完成时操作系统内核会通知应用程序调用预先指定的回调函数。 应用程序在回调函数中处理已完成的I/O操作获取操作结果或进行后续处理。 异步非阻塞I/O模型的主要优势在于允许应用程序以非阻塞且异步的方式进行I/O操作从而提高系统的并发性能和响应能力。应用程序可以发起多个I/O操作而无需等待每个操作的完成从而充分利用CPU资源处理其他任务。 使用异步非阻塞I/O模型的关键是处理已完成的I/O操作。应用程序需要通过回调函数或其他方式处理已完成的操作例如获取操作结果、进行后续处理或发起新的操作。这种异步处理方式可能需要更复杂的编程模式和技巧但它可以提供更高性能和更好的可扩展性。 3.1. Linux AIO 在Linux操作系统中异步I/OAIOAPI主要由以下几个组件和函数组成 aio.h头文件头文件定义了与异步I/O相关的结构体和函数原型。 struct aiocb {int aio_fildes; // File Descriptorint aio_lio_opcode; // Valid only for lio_listio (r/w/nop)volatile void ∗aio_buf; // Data Buffersize_t aio_nbytes; // Number of Bytes in Data Bufferstruct sigevent aio_sigevent; // Notification Structure/∗ Internal fields ∗/...};struct aiocb 这是一个用于描述异步I/O操作的结构体。它包含了操作的参数和状态信息如文件描述符、缓冲区地址、操作类型等。Linux操作系统的AIO API API函数描述aio_read()发起异步读取操作aio_write()发起异步写入操作aio_error()检查异步I/O操作的错误状态aio_return()获取异步I/O操作的返回值aio_suspend()等待一组异步I/O操作完成aio_cancel()取消尚未完成的异步I/O操作aio_init()初始化异步I/O运行时环境aio_fini()销毁异步I/O运行时环境struct aiocb异步I/O操作的参数和状态信息的结构体aio_buf异步I/O操作的缓冲区地址aio_nbytes异步I/O操作的字节数aio_offset异步I/O操作的偏移量aio_lio_opcode异步I/O操作的操作类型aio_sigevent异步I/O操作完成时的信号事件 通过使用上述函数和结构体开发者可以在Linux系统上实现异步I/O操作。可以在编程语言中使用对应的系统调用或库函数来调用这些API如C语言中的系统调用或使用libaio库。 3.2. 我们用C写一个简单的示例 感受一下AIO 的调用方式,说白了就是依赖了Linux 的AIO类库在应用层其实很简单。 使用aio_read函数进行异步读取。打开一个名为aaa.txt的文件并使用aio_read函数发起异步读取操作。通过设置struct aiocb结构体的相关字段包括文件描述符、缓冲区地址、读取字节数和偏移量等。然后使用aio_read函数发起异步读取操作。 在读取操作完成之前可以使用aio_error函数来检查操作的状态如果状态为EINPROGRESS表示操作仍在进行中需要等待。 一旦异步读取操作完成可以使用aio_return函数获取读取的字节数。如果返回值为-1则表示读取操作失败。输出读取到的数据并关闭文件。 #include stdio.h #include stdlib.h #include fcntl.h #include aio.h #include errno.h #include unistd.h#define BUFFER_SIZE 1024int main() {int fileDescriptor;struct aiocb aioRequest;char buffer[BUFFER_SIZE];// 打开文件fileDescriptor open(aaa.txt, O_RDONLY);if (fileDescriptor -1) {perror(Failed to open file);exit(1);}// 设置异步I/O请求aioRequest.aio_fildes fileDescriptor;aioRequest.aio_buf buffer;aioRequest.aio_nbytes BUFFER_SIZE;aioRequest.aio_offset 0;// 发起异步读取操作if (aio_read(aioRequest) -1) {perror(Failed to initiate aio_read);exit(1);}// 等待异步读取操作完成while (aio_error(aioRequest) EINPROGRESS);// 检查异步读取操作的结果ssize_t bytesRead aio_return(aioRequest);if (bytesRead -1) {perror(Failed to complete aio_read);exit(1);}// 输出读取到的数据printf(Read %zd bytes:\n, bytesRead);printf(%.*s, (int)bytesRead, buffer);// 关闭文件close(fileDescriptor);return 0; }现在大家应该已经了解了 AIO 基本函数我们再聊聊可用于异步通知的方法。我将通过信号和函数回调来进一步了解异步通知。上一段我们聊到了AIO的核心是增加了回调通知那么回调通知到底是怎么一回事。 3.3. 异步通知的实现方式 异步通知是指在异步I/O操作完成时通过通知机制来通知应用程序。它允许应用程序在进行异步I/O操作的同时进行其他任务而不需要主动轮询或阻塞等待操作完成。 在异步I/O中异步通知的实现通常涉及以下几个组件 3.3.1. 信号Signal 操作系统可以通过信号机制向应用程序发送信号来通知异步I/O操作的完成。应用程序可以使用信号处理函数来处理接收到的信号。 信号Signal是一种在UNIX和类UNIX操作系统中用于进程间通信IPC和处理异步事件的机制。它是一种软件中断用于通知进程发生了某种事件或异常。 信号可以由内核或进程本身生成并被发送给目标进程。当目标进程接收到信号时可以采取相应的动作来处理信号。常见的信号动作包括执行预定义的信号处理函数忽略信号终止进程等。 每个信号都有一个唯一的数字标识符通常用整数表示。例如SIGINT代表终端中断信号通常由用户在终端上按下CtrlC生成。SIGSEGV代表段错误信号当进程访问无效的内存地址时会生成该信号。 应用程序可以通过以下方式与信号进行交互 捕获信号 应用程序可以注册信号处理函数当指定信号发生时操作系统会调用该函数。通过捕获信号应用程序可以执行自定义的操作来响应信号的发生。 忽略信号 应用程序可以选择忽略某个信号。当忽略信号时操作系统不会采取任何动作信号被丢弃。 默认动作 每个信号都有一个默认的动作例如终止进程或产生核心转储文件。应用程序可以选择恢复信号的默认动作。 常见的一些信号包括 SIGINT终端中断信号通常由用户在终端上按下CtrlC生成。SIGSEGV段错误信号当进程访问无效的内存地址时会生成该信号。SIGTERM终止信号用于请求进程正常终止。SIGKILL强制终止信号用于立即终止进程无法被阻塞或忽略。 我们用C做一个简单的示例。使用信号来捕获和处理SIGINT信号终端中断信号 定义 handle_signal信号处理函数。当接收到SIGINT信号时该函数会打印一条消息并退出程序。 在main函数中我们使用signal函数将SIGINT信号与handle_signal函数进行关联即注册信号处理函数。 然后程序进入一个无限循环等待信号的发生。当用户在终端上按下CtrlC时会生成SIGINT信号操作系统会调用注册的信号处理函数来处理该信号。 #include stdio.h #include stdlib.h #include signal.h// 信号处理函数 void handle_signal(int signum) {if (signum SIGINT) {printf(Received SIGINT signal. Exiting...\n);// 可在此处执行自定义的退出操作exit(0);} }int main() {// 注册信号处理函数signal(SIGINT, handle_signal);printf(Press CtrlC to send SIGINT signal.\n);// 无限循环等待信号while (1) {// 等待信号发生}return 0; }3.3.2. 完成端口Completion Port Windows操作系统提供的一种强大的异步通知机制特别适用于异步I/O操作密集的应用场景。 Completion Port完成端口是一种高效的异步通知机制主要用于Windows操作系统。它提供了一种可扩展的方式来处理异步I/O操作的完成通知和结果获取。 在使用完成端口的模型中应用程序将异步I/O操作与完成端口关联。当异步I/O操作完成时操作系统会将完成的结果发送到关联的完成端口。应用程序可以通过调用特定的函数从完成端口获取操作的结果。 完成端口的主要优点是它对于大规模的异步I/O操作非常高效。它使用了一种事件驱动的模型允许应用程序同时处理多个异步操作的完成事件而无需阻塞或轮询等待。此外完成端口还支持多线程并发处理操作结果提供了更好的性能和可伸缩性。 在使用完成端口时应用程序需要执行以下步骤 创建完成端口应用程序通过调用特定的函数创建一个完成端口。 关联异步I/O操作应用程序将异步I/O操作与完成端口关联通常使用操作相关的结构体或句柄来标识操作。 等待操作完成应用程序通过调用特定的函数等待任意一个或多个操作完成。这个函数会阻塞应用程序直到有操作完成。 处理操作结果一旦操作完成应用程序可以从完成端口获取操作的结果包括读取的数据、错误码等。 3.3.3. 事件驱动Event-driven 事件驱动模型是一种高效处理异步I/O操作的方式特别适用于大量并发操作或高吞吐量场景。在事件驱动模型中应用程序利用事件循环来监听并处理I/O操作的完成事件。以下是事件驱动模型的主要组成部分和工作流程 内容参考和图片来源 https://www.scylladb.com/glossary/event-driven-architecture/ 事件循环事件循环是事件驱动模型的核心组件。它持续运行监听事件队列中的事件并在事件发生时调用相应的回调函数。 事件事件是应用程序中发生的特定动作或状态改变例如文件读取完成、连接建立成功等。事件可以在事件队列中排队等待事件循环处理。 回调函数回调函数是事件处理的代码片段。当事件循环检测到事件发生时它会调用相应的回调函数。回调函数通常需要在事件发生之前注册到事件循环中以便事件循环知道如何处理特定事件。 事件驱动模型的工作流程如下 应用程序启动事件循环。 应用程序向事件循环注册回调函数并发起异步I/O操作。 事件循环监听事件队列中的事件。一旦检测到事件发生事件循环会调用相应的回调函数。 回调函数处理完成的操作并在需要时发起新的异步I/O操作。 事件循环继续监听事件队列中的事件直到应用程序结束。 事件驱动模型的一个主要优势是能够更有效地处理大量并发操作因为它避免了为每个操作创建单独的线程所带来的开销。在高并发和高吞吐量场景下事件驱动模型可以显著提高应用程序的性能。 3.3.4. 回调函数Callback 应用程序可以在发起异步I/O操作时指定一个回调函数。当操作完成时系统会自动调用该回调函数来通知应用程序。 使用异步通知机制可以提高异步I/O的效率和可扩展性避免了不必要的轮询和阻塞等待操作完成。应用程序可以在操作完成后立即处理结果或继续进行其他任务而无需等待操作完成。 。 Java的异步非阻塞I/OAIO模型使用NIO.2Java 7中引入中的AsynchronousFileChannel、AsynchronousSocketChannel等类来实现。在AIO模型中通知回调函数通过实现CompletionHandler接口来处理异步操作的结果。 我们用个示例程序来理解 ReadCompletionHandler的回调类当异步文件读取操作完成时会自动调用它的completed或failed方法。然后我们使用AsynchronousFileChannel异步读取文件并将ReadCompletionHandler的实例作为参数传递给read方法。当读取操作完成时ReadCompletionHandler中的方法将被自动调用以处理操作结果。 实现CompletionHandler接口。这个接口有两个方法completed用于处理操作成功的情况failed用于处理操作失败的情况。 public class ReadCompletionHandler implements CompletionHandlerInteger, ByteBuffer {Overridepublic void completed(Integer bytesRead, ByteBuffer buffer) {System.out.println(异步读取完成读取了 bytesRead 字节);buffer.flip();byte[] data new byte[buffer.limit()];buffer.get(data);System.out.println(文件内容: new String(data));}Overridepublic void failed(Throwable exc, ByteBuffer attachment) {System.err.println(异步读取失败: exc.getMessage());} }使用AsynchronousFileChannel来异步读取文件内容。通知回调函数通过将ReadCompletionHandler的实例传递给AsynchronousFileChannel的read方法来实现。 public class AsyncFileReader {public static void main(String[] args) {Path filePath Paths.get(example.txt);try (AsynchronousFileChannel fileChannel AsynchronousFileChannel.open(filePath, StandardOpenOption.READ)) {ByteBuffer buffer ByteBuffer.allocate(1024);long position 0;fileChannel.read(buffer, position, buffer, new ReadCompletionHandler());// 使程序运行一段时间以便异步操作完成Thread.sleep(3000);} catch (IOException | InterruptedException e) {e.printStackTrace();}} }4. 直接内存IODirect IODIO 基本概念和原理直接将数据从磁盘读取到应用程序所使用的内存空间而不需要经过操作系统内核缓冲区。优点减少数据的拷贝次数提高读写性能。缺点需要操作系统支持适用性较低。应用场景适用于大文件读写等高性能要求的场景。 3. IO多路复用 3.1. 多路复用的概念和原理 selectpollepoll都是IO多路复用的机制。所谓I/O多路复用机制就是说通过一种机制可以监视多个描述符一旦某个描述符就绪一般是读就绪或者写就绪能够通知程序进行相应的读写操作。但selectpollepoll本质上都是同步I/O因为他们都需要在读写事件就绪后自己负责进行读写也就是说这个读写过程是阻塞的而异步I/O则无需自己负责进行读写异步I/O的实现会负责把数据从内核拷贝到用户空间。 3.2. select模型 通过select函数监听多个IO事件当有事件发生时返回适用于连接数较少的场景。监视多个文件描述符例如套接字socket的状态变化。当我们需要监视多个文件描述符时select模型可以帮助我们实现高并发和高性能的网络应用。 select使用一个描述符集来保存需要监控的文件描述符通常为socket。当某个描述符的状态发生变化例如数据可读、可写或异常select函数返回告知哪些描述符发生了变化。 select模型的主要优点是跨平台兼容性好支持多种操作系统。但是在处理大量并发连接时它存在一些缺点 效率较低每次调用select函数时都需要将所有的文件描述符集复制到内核空间。当监视的文件描述符数量较多时这会导致较多的内核态和用户态之间的切换影响性能。可监视的文件描述符数量受限由于select使用fd_set结构存储文件描述符这个结构的大小是固定的限制了select能够监控的最大文件描述符数量。事件触发后需要遍历整个文件描述符集合来确定哪些描述符发生了变化这在大量并发连接的情况下会造成一定的性能损失。 尽管如此select仍然是一种简单而实用的I/O复用技术对于一些并发连接数量较小的应用场景select模型的性能表现仍然可接受。 3.3. poll模型 poll模型是一种高级的I/O复用技术与select类似也用于监视多个文件描述符例如套接字socket的状态变化。poll模型和select模型有很多相似之处但也有一些关键的改进使其在处理大量并发连接时表现更好。 poll模型使用一个轮询结构数组pollfd结构数组来保存需要监控的文件描述符及其关注的事件。当某个描述符的状态发生变化时poll函数返回告知哪些描述符发生了变化及其具体的状态变化。 poll模型的主要优点如下 没有文件描述符数量限制与select不同poll模型不使用固定大小的结构来存储文件描述符而是使用动态大小的轮询结构数组。因此poll没有固定的文件描述符数量限制可以处理更多的并发连接。更高效的事件处理poll在轮询结构数组中直接存储了发生状态变化的描述符及其具体的状态变化信息因此在事件触发后我们可以直接访问这些信息无需像select那样遍历整个文件描述符集合。 然而poll模型在处理大量并发连接时仍存在一些效率问题 执行效率受限于线性轮询当并发连接数量较大时需要遍历整个轮询结构数组以查找发生变化的描述符这会导致一定的性能损失。需要与内核进行大量数据交换每次调用poll函数时都需要将整个轮询结构数组复制到内核空间。当监视的文件描述符数量较多时这会导致较多的内核态和用户态之间的切换影响性能。 poll模型是一种相对于select更加高效的I/O复用技术适用于处理较大数量的并发连接。然而在极高并发的场景下它仍可能面临一些性能问题。针对这些问题可以考虑使用更高效的I/O复用技术如epollLinux或IOCPWindows。 在操作系统层面poll模型主要通过系统调用来实现。在Linux和类Unix系统中poll模型通过poll()系统调用来实现。这个系统调用可以让应用程序轮询多个文件描述符包括套接字、普通文件等的I/O状态从而实现多路复用。下面从操作系统层面详细解释poll模型的工作原理。 文件描述符 在Unix和类Unix系统中所有打开的文件、套接字、管道等都用一个非负整数表示称为文件描述符file descriptor。文件描述符用于唯一标识一个打开的文件并提供一个统一的接口用于读、写和操作文件。 pollfd结构体 poll模型使用一个名为pollfd的结构体数组来存储需要监视的文件描述符及其关注的事件。pollfd结构体包含以下字段 int fd表示文件描述符。short events表示关注的事件例如POLLIN表示关注输入事件可读POLLOUT表示关注输出事件可写。short revents表示文件描述符实际发生的事件。当poll()函数返回时该字段会被设置为发生的事件类型。 poll()系统调用 poll模型通过poll()系统调用来查询文件描述符的状态。poll()函数的原型如下 int poll(struct pollfd *fds, nfds_t nfds, int timeout);其中fds是指向pollfd结构体数组的指针nfds表示数组中文件描述符的数量timeout表示等待时间以毫秒为单位-1表示无限等待0表示立即返回。 当我们调用poll()函数时操作系统会将pollfd结构体数组复制到内核空间然后检查每个文件描述符的状态。如果某个文件描述符的状态发生了变化例如可读或可写操作系统会将对应的revents字段设置为相应的事件类型。当检查完所有文件描述符后poll()函数返回并将pollfd结构体数组复制回用户空间。此时我们可以遍历数组检查每个文件描述符的revents字段以确定发生了哪些事件。 从操作系统的角度来看poll模型的优缺点 优点 可以处理大量文件描述符由于poll模型使用动态大小的数组来存储文件描述符因此没有文件描述符数量的固定限制。 直接返回发生事件的文件描述符与select模型相比poll模型在数组中直接存储了发生事件的文件描述符及其具体的事件类型。这使得我们可以更快地处理事件而无需像select那样遍历整个文件描述符集合。 缺点 线性查找效率低当文件描述符数量较多时查找发生事件的文件描述符需要遍历整个数组导致效率较低。 频繁的用户态和内核态切换每次调用poll()函数时都需要将整个pollfd数组复制到内核空间然后再复制回用户空间。这会导致较多的用户态和内核态切换影响性能。 3.4. epoll模型 epoll是Linux内核中一种高效的I/O事件处理模型。它是Linux下多路复用I/O接口select和poll的增强版本。其主要优点是在处理大量并发连接时性能较高且没有固定限制。以下将详细解释epoll的工作原理、使用方法和优缺点。 许多流行的开源中间件使用了epoll模型来实现高性能的并发处理能力 这些中间件都运用了epoll模型使得它们能够在高并发环境下表现出卓越的性能。 Nginx采用了epoll模型来实现高并发和高吞吐量。Redis epoll模型来处理大量的并发连接。Haproxy 它一个开源的负载均衡器和代理服务器采用了epoll模型来实现高并发和高可用性。 3.4.1. 工作原理 epoll使用一种事件驱动机制它会将多个I/O事件注册到一个epoll对象上然后在事件发生时通知应用程序。与select和poll不同的是epoll并不需要遍历整个监听集合而是基于内核回调来实现这样就避免了线性扫描的开销。此外epoll只会返回已经发生的事件因此处理效率更高。 3.4.2. 使用方法 以下是使用epoll的基本步骤 创建epoll对象通过调用epoll_create或epoll_create1函数来创建一个epoll对象。注册事件使用epoll_ctl函数将需要监听的文件描述符如socket、文件等及其关联的事件如EPOLLIN、EPOLLOUT等添加到epoll对象中。等待事件通过调用epoll_wait函数来等待注册的事件发生。当事件发生时epoll_wait返回已经就绪的事件集合。处理事件根据epoll_wait返回的事件集合执行相应的事件处理操作。注销事件如果不再需要监听某个文件描述符可以调用epoll_ctl将其从epoll对象中删除。关闭epoll对象使用close函数关闭epoll对象。 3.4.3. 优缺点 优点缺点事件驱动只会返回已经发生的事件避免了线性扫描的开销。只适用于Linux不具备跨平台性。没有固定限制可以处理大量并发连接。学习曲线较高相较于select和pollepoll的API更复杂学习成本较高。对于大量连接epoll性能优于select和poll。对于少量连接其优势不明显而且使用也相对复杂。 3.5. kqueue模型 类似于epoll模型但在Unix-like系统中使用适用于高并发的场景。 3.6. IOCP模型 IOCPI/O Completion Ports是Windows操作系统下的一种高性能I/O模型。IOCP为高并发、高吞吐量的网络应用提供了高效且可扩展的I/O操作。在IOCP模型中所有的I/O操作都是异步进行的核心思想是将I/O操作与处理I/O完成的工作线程分离使得线程能够专注于处理逻辑。 3.6.1. IOCP的主要组成部分 完成端口Completion Port一种特殊的操作系统对象用于管理和处理异步I/O操作的完成通知。完成例程Completion Routine处理异步I/O操作完成通知的回调函数。OVERLAPPED结构用于描述异步I/O操作的数据结构包含了完成例程、完成键和其他相关信息。 3.6.2. IOCP模型的工作流程 创建一个完成端口 应用程序创建一个完成端口用于接收和处理I/O完成通知。关联文件描述符 将socket或其他文件描述符与完成端口关联使得socket上的I/O操作能够被完成端口处理。发起异步I/O操作 当需要进行I/O操作如发送、接收数据等时应用程序发起一个异步I/O操作。这个操作会立即返回线程继续处理其他任务。等待I/O完成 工作线程通过调用GetQueuedCompletionStatus()函数等待I/O操作的完成通知。当有完成通知时函数返回并提供相关的完成信息。处理完成通知 工作线程根据完成信息调用相应的完成例程处理I/O操作的结果并进行下一步处理如继续发起异步I/O操作等。 3.7. 优缺点比较 实现方式优点缺点select1. 跨平台支持良好可移植性高。 2. 简单易用适合入门学习。1. 文件描述符数量受FD_SETSIZE限制默认为1024。 2. 系统调用开销较大需要遍历整个文件描述符集合。 3. 触发方式为水平触发Level-Triggered容易导致性能问题。poll1. 跨平台支持良好可移植性高。 2. 无文件描述符数量限制。1. 系统调用开销较大同样需要遍历文件描述符集合。 2. 触发方式为水平触发Level-Triggered容易导致性能问题。epoll1. Linux平台专属性能优秀。 2. 无文件描述符数量限制。 3. 系统调用开销较小可实现事件驱动。 4. 支持边缘触发Edge-Triggered和水平触发Level-Triggered。1. 仅适用于Linux平台可移植性差。 2. 使用边缘触发模式时编程复杂度较高。kqueue1. BSD平台专属性能优秀。 2. 无文件描述符数量限制。 3. 系统调用开销较小可实现事件驱动。 4. 支持边缘触发Edge-Triggered和水平触发Level-Triggered。1. 仅适用于BSD平台如FreeBSD、macOS等可移植性差。 2. 使用边缘触发模式时编程复杂度较高。IOCPWindows1. Windows平台专属性能优秀。 2. 基于完成端口的事件通知机制可实现事件驱动。 3. 支持异步操作适用于高并发场景。1. 仅适用于Windows平台可移植性差。 2. 编程复杂度较高。 参考文档 《Boost application performance using asynchronous I/O》及图片来源自本文 https://notes.shichao.io/unp/ch6/ http://www.linuxidc.com/Linux/2012-05/59873p3.htm http://xingyunbaijunwei.blog.163.com/blog/static/76538067201241685556302/ http://blog.csdn.net/kkxgx/article/details/7717125 https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/epoll-example.c
http://www.zqtcl.cn/news/232286/

相关文章:

  • 产品网站建设框架wordpress用户名密码加密方式
  • 入侵dedecms网站管理员密码青岛seo整站优化公司
  • 小网站备案南宁网站建设排名
  • 西安免费做网站wordpress 使用方法
  • 企业营销的意义优化核心系列网站
  • 微信网站设计一起做网站17广州
  • 重庆网络推广网站如何制作app演示视频
  • 网站logo是指手机上做app的软件
  • 做母婴育儿类网站好做seo排名吗深圳网站. 方维网络
  • 小型装修公司店面装修windows优化大师会员
  • php服装商城网站建设wordpress主题去除友情链接
  • 北京网站设计公司sx成都柚米科技15福建众利建设工程网站
  • 深圳大型网站建设服务公司wordpress后台为什么这么慢
  • 信用网站建设工作简报青岛的建筑公司
  • 网站怎么做文件上传灯饰 东莞网站建设
  • 建设电子商务网站的规划书电子商务平台网站模板
  • 桂林网站建设 腾云安康养老院收费
  • 网站建设找酷风旅游手机网站开发
  • 宜昌建设厅网站开发公司起名大全
  • 龙口建设局网站深圳十大网站建设公司
  • 湛江网站设计哪家好公司网址怎么查询
  • 网站怎么设置关键词河南宣传片制作公司
  • 做网站 怎么赚钱吗安乡网站制作
  • 国外展览展示设计网站沧州网络推广管理公司
  • 物流信息平台网站建设深圳做手机网站建设
  • 品牌型网站的特点领导视察网站建设
  • 如何自己做网站推广淘宝客佛山小程序开发公司
  • 天津市建设局网站口碑营销相关案例
  • 怎么有自己的网站厂字形网页布局网站
  • 广州市财贸建设开发监理网站工程建设企业等采用