POSIX 线程 - 使用条件变量 MEMORY LEAK 同步分离的线程
POSIX Threads - synchronize DETACHED threads using conditional variable MEMORY LEAK
您好,我正在尝试使用条件变量同步分离的线程,但我发现了一个有时会导致内存泄漏的错误(取决于调度程序的心情)。我认为代码是不言自明的。我将不胜感激任何建议。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <pthread.h>
using namespace std;
struct TThrArg
{
pthread_t m_ID;
bool m_IsRunning;
};
TThrArg g_Threads[64];
int g_Counter;
pthread_mutex_t g_Mtx;
pthread_cond_t g_Cond;
void * thrFunc ( void * arg )
{
TThrArg * data = (TThrArg *) arg;
// do some stuff
// -----------------------------------
// for ( int i = 0; i < 5000; ++i )
// for ( int j = 0; j < 5000; ++j )
// int x = 0;
// printf("Thread: %lu running...n", data->m_ID);
// -----------------------------------
pthread_mutex_lock(&g_Mtx);
memset(data, 0, sizeof(TThrArg));
--g_Counter;
pthread_cond_signal(&g_Cond);
pthread_mutex_unlock(&g_Mtx);
sleep(1); // --> this spot causes that main may end before return NULL so resources will not be freed
return NULL;
}
void createThread ( void )
{
pthread_mutex_lock(&g_Mtx);
for ( int i = 0; i < 64; ++i )
{
if ( g_Threads[i].m_IsRunning == 0 )
{
g_Threads[i].m_IsRunning = 1;
++g_Counter;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&g_Threads[i].m_ID, &attr, thrFunc, &g_Threads[i]);
pthread_attr_destroy(&attr);
break;
}
}
pthread_mutex_unlock(&g_Mtx);
}
int main ( int argc, char * argv[] )
{
pthread_mutex_init(&g_Mtx, NULL);
pthread_cond_init(&g_Cond, NULL);
g_Counter = 0;
for ( int i = 0; i < 64; ++i )
createThread();
pthread_mutex_lock(&g_Mtx);
while ( g_Counter != 0 )
{
pthread_cond_wait(&g_Cond, &g_Mtx);
}
pthread_mutex_unlock(&g_Mtx);
pthread_mutex_destroy(&g_Mtx);
pthread_cond_destroy(&g_Cond);
return 0;
}
您看到的泄漏是因为终止线程会减少受互斥锁保护的线程计数器,并在线程实际终止之前暂停一秒钟。
主执行线程将立即看到线程计数器达到 0,并在实际分离的线程退出之前终止。每个正在运行的线程(甚至是分离的线程)都会消耗和分配一点内部存储器,直到线程实际终止才会释放。这是您看到的泄漏,来自在主执行线程停止之前未终止的执行线程。
这不是您需要担心的泄漏类型。这很烦人,并且使调试变得困难,这是真的。
过去,我在前段时间编写的框架类库中采用了一种方法。我根本没有使用分离的线程,但所有线程都是可连接的线程。该框架启动了一个单例后台线程,其唯一工作是join()
终止的线程。然后,框架启动的每个线程将在每个线程终止之前,为单一实例后台线程排队自己的线程 ID。
净效应相当于分离的线程。我可以启动每个线程,而不必担心加入它。这将是后台线程的工作。框架将向后台线程发出信号,使其在退出之前自行终止并加入它。因此,如果一切顺利,将不会有任何报告的内存泄漏可以归因于线程支持。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在C++中使用cURL和多线程
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在cuda线程之间共享大量常量数据
- 如何将元素添加到数组的线程安全函数?
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 异常属于C++中的线程还是进程
- C++中的线程安全删除
- C++使用params创建线程函数会导致转换错误
- 类与私有变量的其他类之间的线程安全性
- CoInitialize()在单独的线程上崩溃而不返回
- c++中的线程池
- 线程之间的布尔停止信号
- 为什么std::async使用同一个线程运行函数
- 用于矢量处理的多个线程
- C++为线程工作动态地分割例程
- POSIX 线程 - 使用条件变量 MEMORY LEAK 同步分离的线程