gpt4 book ai didi

threadpool - 使用 Windows ThreadPool API 的内存泄漏

转载 作者:行者123 更新时间:2023-12-03 11:18:22 26 4
gpt4 key购买 nike

我在我的应用程序中使用 Windows ThreadPools,每次调用 CreateThreadPoolWork() 时都会遇到 136 字节的内存泄漏,如通过 UMDH 所见:

+ 1257728 ( 1286424 -  28696)   9459 allocs BackTraceB0035CC
+ 9248 ( 9459 - 211) BackTraceB0035CC allocations

ntdll!RtlUlonglongByteSwap+B52
ntdll!TpAllocWork+8D
KERNEL32!CreateThreadpoolWork+25
... My Code ...

我正在使用 Cleanup Group,因此根据文档我没有调用 CloseThreadPoolWork()。

我处理线程池的代码是:

typedef PTP_WORK ThreadHandle_t;
typedef PTP_WORK_CALLBACK THREAD_ENTRY_POINT_T;

static PTP_POOL pool = NULL;
static TP_CALLBACK_ENVIRON CallBackEnviron;
static PTP_CLEANUP_GROUP cleanupgroup = NULL;

int mtInitialize()
{
InitializeThreadpoolEnvironment(&CallBackEnviron);

pool = CreateThreadpool(NULL);

if (NULL == pool)
{
return -1;
}

cleanupgroup = CreateThreadpoolCleanupGroup();

if (NULL == cleanupgroup)
{
return -1;
}

SetThreadpoolCallbackPool(&CallBackEnviron, pool);

SetThreadpoolCallbackCleanupGroup(&CallBackEnviron, cleanupgroup, NULL);

return 0; // Success
}

void mtDestroy()
{
CloseThreadpoolCleanupGroupMembers(cleanupgroup, FALSE, NULL);
CloseThreadpoolCleanupGroup(cleanupgroup);
DestroyThreadpoolEnvironment(&CallBackEnviron);
CloseThreadpool(pool);
}

//Create thread
ThreadHandle_t mtRunThread(THREAD_ENTRY_POINT_T entry_point, void *thread_args)
{
PTP_WORK work = NULL;

work = CreateThreadpoolWork(entry_point, thread_args, &CallBackEnviron);

if (NULL == work) {
// CreateThreadpoolWork() failed.
return 0;
}

SubmitThreadpoolWork(work);

return work;
}

//Wait for a thread to finish
void mtWaitForThread(ThreadHandle_t thread)
{
WaitForThreadpoolWorkCallbacks(thread, FALSE);
}

我做错了什么吗?知道我为什么会泄漏内存吗?

最佳答案

根据您的评论,我猜您已经明白了,但问题是您只在 mtDestroy() 中调用了 CloseThreadpoolCleanupGroupMembers()

如果您有一个持久线程池,除非您定期调用 CloseThreadpoolCleanupGroupMembers(),否则内存将不会被释放。您的代码和评论表明您这样做,但如果没有负责创建和销毁线程池的代码我无法确认这一点。

我对持久线程池的建议是在回调函数中调用 CloseThreadpoolWork()。如果您要创建和销毁线程池,Microsoft 的建议会更好,但是如果您要维护一个线程池,CloseThreadpoolWork() 比定期调用 CloseThreadpoolCleanupGroupMembers() 更简单、更容易在您的应用程序的生命周期内。

顺便说一句,只要您告诉 CloseThreadpoolCleanupGroupMembers() 取消任何未决回调(将 fCancelPendingCallbacks 作为 TRUE) 以确保在任何已清理的工作项上调用 CloseThreadpoolWork():

You can revoke the work object’s membership only by closing it, which can be done on an individual basis with the CloseThreadpoolWork function. The thread pool knows that the work object is a member of the cleanup group and revokes its membership before closing it. This ensures that the application doesn’t crash when the cleanup group later attempts to close all of its members. The inverse isn’t true: If you first instruct the cleanup group to close all of its members and then call CloseThreadpoolWork on the now invalid work object, your application will crash.

来自 Windows with C++ - Thread Pool Cancellation and Cleanup

关于threadpool - 使用 Windows ThreadPool API 的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13705528/

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