【问题标题】:POSIX Threads - synchronize DETACHED threads using conditional variable MEMORY LEAKPOSIX 线程 - 使用条件变量 MEMORY LEAK 同步 DETACHED 线程
【发布时间】:2016-04-24 16:09:08
【问题描述】:

您好,我正在尝试使用条件变量同步分离的线程,但我发现了一个有时会导致内存泄漏的错误(取决于调度程序的情绪)。我认为代码是不言自明的。如有任何建议,我将不胜感激。

#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;
}

【问题讨论】:

    标签: c++ multithreading memory-leaks posix


    【解决方案1】:

    您看到的泄漏是因为终止线程递减受互斥体保护的线程计数器,并在线程实际终止之前暂停一秒钟。

    主执行线程将立即看到线程计数器达到 0,并在实际分离的线程退出之前终止。每个正在运行的线程,甚至是分离的线程,都会消耗并分配一点内部内存,直到线程实际终止时才会释放这些内存。这是您看到的泄漏,来自在主执行线程停止之前没有终止的执行线程。

    这不是您需要担心的泄漏类型。确实很烦人,并且使调试变得困难。

    过去,我在前段时间编写的框架类库中采用了一种方法。我根本没有使用分离线程,但所有线程都是可连接线程。框架启动了一个单例后台线程,其唯一的工作是join() 已终止的线程。然后,框架启动的每个线程将在每个线程终止之前为单例后台线程排队自己的线程 ID。

    最终效果等同于分离线程。我可以启动每个线程而不必担心加入它。这将是后台线程的工作。框架会在退出之前向后台线程发出信号以终止自身并加入它。因此,如果一切顺利,将不会报告任何可归因于线程支持的内存泄漏。

    【讨论】:

    • 感谢您的信息,但是否有任何“干净”的方法可以通过编辑上面的代码来防止泄漏?
    • 不。知道线程使用的所有资源都已释放的唯一方法是加入它。在线程中执行的最后一个操作与线程实际终止并释放其所有资源之间总是存在竞争条件。
    • 非常感谢先生。
    猜你喜欢
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 2014-05-13
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-11
    相关资源
    最近更新 更多