Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ pthread_create()和内存泄漏_C++_Multithreading_Memory Leaks_Pthreads - Fatal编程技术网

C++ pthread_create()和内存泄漏

C++ pthread_create()和内存泄漏,c++,multithreading,memory-leaks,pthreads,C++,Multithreading,Memory Leaks,Pthreads,这个问题似乎被问了很多。我有一些遗留的生产代码,看起来不错,直到它开始每天获得更多的连接。每个连接启动一个新线程。最终,它将耗尽内存并崩溃 我将回顾一下pthread(和C套接字),我已经多年没有处理过它们了。我的教程内容丰富,但我在使用top时也看到了同样的情况。所有线程都退出,但仍有一些虚拟内存被占用。Valgrind告诉我调用pthread_create()时可能会丢失内存。下面是非常基本的示例代码 最可怕的是,当所有线程退出时,pthread_exit(NULL)似乎在VIRT中留下了大

这个问题似乎被问了很多。我有一些遗留的生产代码,看起来不错,直到它开始每天获得更多的连接。每个连接启动一个新线程。最终,它将耗尽内存并崩溃

我将回顾一下pthread(和C套接字),我已经多年没有处理过它们了。我的教程内容丰富,但我在使用top时也看到了同样的情况。所有线程都退出,但仍有一些虚拟内存被占用。Valgrind告诉我调用pthread_create()时可能会丢失内存。下面是非常基本的示例代码

最可怕的是,当所有线程退出时,pthread_exit(NULL)似乎在VIRT中留下了大约100万个未解释的内容。如果我把这一行注释掉,它更适合居住,但仍然有一些。在我的系统上,它从大约14k开始,到47k结束

如果我将线程数增加到10000,VIRT将增加到70多个gig,但在大约50k处结束,假设我注释掉pthread_exit(NULL)。如果我使用pthread_exit(NULL),它将在VIRT中完成约113m。这些可以接受吗?托普没有告诉我一切吗

void* run_thread( void* id )
{
    int thread_id = *(int*)id;
    int count = 0;
    while ( count < 10 ) {
        sleep( 1 );
        printf( "Thread %d at count %d\n", thread_id, count++ );
    }

    pthread_exit( NULL );
    return 0;
}

int main( int argc, char* argv[] )
{
    sleep( 5 ); 
    int thread_count    = 0;
    while( thread_count < 10 ) {
        pthread_t my_thread;
        if ( pthread_create( &my_thread, NULL, run_thread, (void*)&thread_count ) < 0 )   {
            perror( "Error making thread...\n" );
            return 1;
        }

        pthread_detach( my_thread );
        thread_count++;
        sleep( 1 );
    }

    pthread_exit( 0 );  // added as per request
    return 0;
}
void*运行线程(void*id)
{
int-thread_-id=*(int*)id;
整数计数=0;
同时(计数<10){
睡眠(1);
printf(“线程%d位于计数%d\n”,线程id,计数++);
}
pthread_exit(NULL);
返回0;
}
int main(int argc,char*argv[])
{
睡眠(5);
int线程计数=0;
同时(螺纹数<10){
pthread\u t我的线程;
if(pthread_create(&my_thread,NULL,run_thread,(void*)和thread_count)<0){
perror(“错误生成线程…\n”);
返回1;
}
pthread_detach(我的线程);
线程计数++;
睡眠(1);
}
pthread_exit(0);//根据请求添加
返回0;
}

在编辑将
pthread\u exit(0)
添加到
main()
的末尾之前,程序将在所有线程完成运行之前完成执行<因此,code>valgrind报告了在程序终止时仍处于活动状态的线程所持有的资源,使程序看起来像是内存泄漏

main()
中调用
pthread\u exit(0)
会使主线程在自身退出之前等待所有其他派生线程退出。这使得
valgrind
可以在内存利用率方面观察到干净的运行

(下面我假设linux是您的操作系统,但从您的评论来看,您似乎正在运行各种各样的UNIX。)

您看到的额外虚拟内存只是linux为您的程序分配了一些页面,因为它是一个大内存用户。只要在达到空闲状态时驻留内存利用率较低且恒定,并且虚拟利用率相对恒定,就可以假定系统性能良好

默认情况下,每个线程在linux上获得2MB的堆栈空间。如果每个线程堆栈不需要那么多空间,可以通过初始化
pthread\u attr\u t
并使用
pthread\u attr\u setstacksize()
将其设置为较小的堆栈大小来调整它。适当的堆栈大小取决于函数调用堆栈增长的深度以及这些函数的局部变量占用的空间

#define SMALLEST_STACKSZ PTHREAD_STACK_MIN
#define SMALL_STACK (24*1024)
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, SMALL_STACK);
/* ... */
pthread_create(&my_thread, &attr, run_thread, (void *)thread_count);
/* ... */
pthread_attr_destroy(&attr);

我知道这是个老问题,但我希望其他人能从中受益。 这确实是内存泄漏。线程是使用默认属性创建的。默认情况下,线程是可连接的。一个可连接的线程将保留其基础簿记,直到它完成。。。加入。 如果线程从未连接,请设置“解除分离”属性。一旦线程终止,所有(线程)资源都将被释放。 下面是一个例子:

pthread_attr_t attr;
pthread_t thread;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, 1);
pthread_create(&thread, &attr, &threadfunction, NULL);
pthread_attr_destroy(&attr);

我想你正在报告你的数字的valgrind结果。在
main()
返回0
之前,是否可以添加
pthread\u exit(0)
。。。不管怎么说,还是和瓦尔格兰德在一起。”“top”似乎仍然表示仍有一些虚拟内存在使用中。该程序在启动线程之前有14k的VIRT,现在在启动线程之后有110m。但这似乎是静态的。无论线程数是10还是1000,VIRT中的100m都存在。我想我应该相信valgrind?是的。valgrind报告内存问题的原因是,在主线程结束之前,并非所有线程都已完成。添加
thread\u exit()
调用修复了这一问题。与内存泄漏无关,但您正在向每个新线程传递相同的本地
thread\u count
变量的地址。根据线程启动的速度,它可能会看到正确的值,也可能会看到更新、更高的值。您需要在堆上分配一个新变量以传递给每个子线程,或者使用一个整数强制转换到
(void*)
。非常感谢--这非常有意义!非常好,谢谢你回答了一个关于子孙后代的老问题。当然,我现在只使用std::thread,它似乎更好地封装了所有这些