找回密码
 立即注册
搜索

C++ 网络编程:完成端口IOCP具体实现

2024-11-18 15:47| 发布者: admin| 查看: 41| 评论: 0|来自: 51CTO

摘要: IOCP(I/O Completion Ports)是Windows操作系统提供的一种高效的异步I/O模型,主要用于处理大量并发I/O请求的应用程序。
IOCP(I/O Completion Ports)是Windows操作系统提供的一种高效的异步I/O模型,主要用于处理大量并发I/O请求的应用程序。

IOCP通过以下几个关键概念来实现高效的异步I/O:

Completion Port:这是一个内核对象,多个I/O操作可以与其关联。每个完成端口可以关联多个线程,用于处理I/O完成事件。
I/O Request Packet (IRP):当一个异步I/O请求被发出时,操作系统会创建一个IRP来跟踪这个I/O操作。完成端口会在I/O操作完成时接收到一个包含I/O结果的消息。
Worker Threads:在使用IOCP的应用程序中,通常会创建一个线程池。这些工作线程会等待从完成端口获取I/O完成的通知,然后处理相应的I/O操作。
Asynchronous I/O:使用IOCP的应用程序通常会发出异步I/O请求,而不是阻塞的同步I/O请求。这允许应用程序在等待I/O操作完成的同时继续处理其他任务,从而提高了并发性能。


IOCP工作流程
创建完成端口:使用CreateIoCompletionPort创建一个完成端口。
关联文件句柄:使用CreateIoCompletionPort将文件句柄(如套接字或文件)与完成端口关联。
发出异步I/O请求:使用异步I/O函数(如ReadFile、WriteFile)发出I/O请求,并提供OVERLAPPED结构。
等待I/O完成:工作线程使用GetQueuedCompletionStatus等待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操作不会阻塞调用线程。调用线程在发出I/O请求后可以立即继续执行其他任务,而操作系统会在I/O操作完成时通知应用程序。

特点
非阻塞:调用线程不必等待I/O操作完成,可以并行处理其他任务,提高了并发性能。
复杂:编程模型相对复杂,需要处理I/O完成的通知和结果。
适用场景:适用于高并发、高吞吐量的应用场景,如服务器和网络编程。
windows异步IO接口
1. CreateIoCompletionPort
CreateIoCompletionPort用于创建一个新的完成端口或将一个文件句柄(如套接字或文件)关联到现有的完成端口。

HANDLE CreateIoCompletionPort(
    HANDLE FileHandle,
    HANDLE ExistingCompletionPort,
    ULONG_PTR CompletionKey,
    DWORD NumberOfConcurrentThreads
);

FileHandle:要关联的文件句柄。如果为INVALID_HANDLE_VALUE,则创建一个新的完成端口。
ExistingCompletionPort:现有的完成端口句柄。如果创建新完成端口,此参数应为NULL。
CompletionKey:与文件句柄关联的完成键,完成端口通知时将返回此键。
NumberOfConcurrentThreads:建议并发线程数。通常设置为系统的CPU核心数。
2. ReadFile 和 WriteFile
ReadFile和WriteFile是常用的异步读写函数。它们的异步操作需要结合OVERLAPPED结构。

BOOL ReadFile(
    HANDLE hFile,
    LPVOID lpBuffer,
    DWORD nNumberOfBytesToRead,
    LPDWORD lpNumberOfBytesRead,
    LPOVERLAPPED lpOverlapped
);

BOOL WriteFile(
    HANDLE hFile,
    LPCVOID lpBuffer,
    DWORD nNumberOfBytesToWrite,
    LPDWORD lpNumberOfBytesWritten,
    LPOVERLAPPED lpOverlapped
);

3. GetQueuedCompletionStatus
GetQueuedCompletionStatus用于从完成端口获取I/O完成通知。调用此函数的线程将被阻塞,直到一个I/O操作完成或超时。

BOOL GetQueuedCompletionStatus(
    HANDLE CompletionPort,
    LPDWORD lpNumberOfBytesTransferred,
    PULONG_PTR lpCompletionKey,
    LPOVERLAPPED* lpOverlapped,
    DWORD dwMilliseconds
);

CompletionPort:完成端口句柄。
lpNumberOfBytesTransferred:接收传输的字节数。
lpCompletionKey:接收完成键。
lpOverlapped:接收指向OVERLAPPED结构的指针。
dwMilliseconds:等待的超时时间,以毫秒为单位。如果为INFINITE,则无限等待。
4. PostQueuedCompletionStatus
PostQueuedCompletionStatus用于将一个完成包投递到完成端口。这在模拟I/O操作或控制工作线程方面很有用。

BOOL PostQueuedCompletionStatus(
    HANDLE CompletionPort,
    DWORD dwNumberOfBytesTransferred,
    ULONG_PTR dwCompletionKey,
    LPOVERLAPPED lpOverlapped
);

CompletionPort:完成端口句柄。
dwNumberOfBytesTransferred:传输的字节数。
dwCompletionKey:完成键。
lpOverlapped:指向OVERLAPPED结构的指针。
5. ReadFileEx 和 WriteFileEx
ReadFileEx和WriteFileEx提供了另一种异步I/O接口,它们通过回调函数通知I/O操作的完成。

复制 
BOOL ReadFileEx(
    HANDLE hFile,
    LPVOID lpBuffer,
    DWORD nNumberOfBytesToRead,
    LPOVERLAPPED lpOverlapped,
    LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

BOOL WriteFileEx(
    HANDLE hFile,
    LPCVOID lpBuffer,
    DWORD nNumberOfBytesToWrite,
    LPOVERLAPPED lpOverlapped,
    LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

C++ 网络编程:完成端口IOCP
https://blog.51cto.com/u_14813976/11709299

路过

雷人

握手

鲜花

鸡蛋

QQ|Archiver|手机版|小黑屋|软件开发编程门户 ( 陇ICP备2024013992号-1|甘公网安备62090002000130号 )

GMT+8, 2024-11-21 14:23 , Processed in 0.034314 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

返回顶部