gpt4 book ai didi

windows - IOCP 循环终止可能导致内存泄漏?如何优雅地关闭 IOCP 循环

转载 作者:可可西里 更新时间:2023-11-01 09:25:17 25 4
gpt4 key购买 nike

我有经典的 IOCP 回调,它以这种方式使 i/o 挂起的请求出列、处理它们并释放它们:

struct MyIoRequest { OVERLAPPED o; /* ... other params ... */ };
bool is_iocp_active = true;

DWORD WINAPI WorkerProc(LPVOID lpParam)
{
ULONG_PTR dwKey;
DWORD dwTrans;
LPOVERLAPPED io_req;
while(is_iocp_active)
{
GetQueuedCompletionStatus((HANDLE)lpParam, &dwTrans, &dwKey, (LPOVERLAPPED*)&io_req, WSA_INFINITE);
// NOTE, i could use GetQueuedCompletionStatusEx() here ^ and set it in the
// alertable state TRUE, so i can wake up the thread with an ACP request from another thread!

printf("dequeued an i/o request\n");
// [ process i/o request ]
...

// [ destroy request ]
destroy_request(io_req);
}
// [ clean up some stuff ]
return 0;
}

然后,在代码中我会在某处:

MyIoRequest * io_req = allocate_request(...params...);
ReadFile(..., (OVERLAPPED*)io_req);

这非常有效。

现在我的问题是:我想立即关闭 IOCP 队列而不造成泄漏怎么办? (例如应用程序必须退出)我的意思是:如果我将 is_iocp_active 设置为“false”,下一次 GetQueuedCompletionStatus() 将出列一个新的 i/o 请求,这将是最后一个 i/o 请求:它将返回,导致线程退出以及线程退出时根据 MSDN,所有挂起的 i/o 请求都被系统简单地取消了。

但是我在调​​用 ReadFile() 时实例化的“MyIoRequest”类型的结构根本不会被销毁:系统已经取消了挂起的 i/o 请求,但我必须手动销毁我拥有的那些结构创建,否则我将在停止循环时泄漏所有未决的 i/o 请求!

那么,我该怎么做呢?仅仅将该变量设置为 false 来停止 IOCP 循环是错误的吗?请注意,即使我使用 APC 请求来停止可警告的线程,也会发生这种情况。

我想到的解决方案是将每个“MyIoRequest”结构添加到队列/列表,然后在 GetQueuedCompletionStatusEx 返回时将它们出队,但这不应该造成一些瓶颈,因为此类 MyIoRequest 的入队/出队过程结构必须互锁?也许我误解了如何使用 IOCP 循环。有人可以阐明这个主题吗?

最佳答案

我通常关闭 IOCP 线程的方式是发布我自己的“请立即关闭”完成。这样您就可以干净地关闭并处理所有未决的完成,然后关闭线程。

执行此操作的方法是调用 PostQueuedCompletionStatus(),其中 num 个字节、完成键和 pOverlapped 为 0。这将意味着完成键是一个唯一值(你不会有一个有效的文件或套接字具有零句柄/完成键)。

第一步是关闭完成源,因此关闭或中止套接字连接、关闭文件等。一旦所有这些都关闭,您就无法再生成任何完成数据包,因此您可以发布特殊的 '0 '完成;为您为 IOCP 提供服务的每个线程发布一个。一旦线程获得“0”完成键,它就会退出。

关于windows - IOCP 循环终止可能导致内存泄漏?如何优雅地关闭 IOCP 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15547741/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com