2012-03-31 11 views
0

スレッドの配列を作成しましたが、それらのすべてを使用するわけではありません。それはメモリリークになります。メモリを解放するために使用できる機能はありますか?c未使用のスレッドをクリーンアップ

void func(args...) 
{ 
. 
. 
. 
pthread_t threads[10] 

int i; 
for(i = 0; i < 8; i++) 
{ 
    /* create 8 threads */ 
} 
for(i = 0; i < 8; i++) 
{ 
    /* join 8 threads */ 
} 
. 
. 
. 
return; 
} 

私が実験に使用したコードはここにあります。私はそれが私がしたいよりも多くのスレッドを使用するようにします。 10個のスレッドを追加しなければ、リークはまったくありません。それは、引数 コンパイルとして、いくつかのテキストファイルを受け取り、

のgcc -g -Wall -pthread test.cの valgrindの--tool = memcheck --leakチェックして実行=フル--show-到達可能=はい./a .out * .txt

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <fcntl.h> 
#include <unistd.h> 

#define DEBUG 0 
#define BUFLEN 10000 

/* function declaration */ 
static void* countLines(void* input); 
static void error(const char*); 

/* global variable */ 
static int total_th; /* total number of threads */ 
static int count_th; /* the count of the finished threads */ 

/* 
* main starts here 
*/ 
int main(int argc, char** argv) 
{ 
    /* if there is no command line arguments, print error */ 
    if(argc < 2) 
    { 
     error("there should be at lease one argument!\n"); 
     exit(-1); 
    } 

    /* initialize thread counters */ 
    total_th = argc - 1; 
    count_th = 0; 

    pthread_t pt[ total_th + 10]; /* the ptreads to read file lines */ 

    /* create threads for each file */ 
    int i; 
    for(i = 0; i < total_th; i++) 
    { 
     if((pthread_create(&pt[i], NULL, 
       countLines, (void*) argv[i + 1])) != 0) 
     { 
      fprintf(stderr, "error in thread create\n"); 
     } 
    } 

    /* main thread wait for all the slaves to finish */ 
    for(i = 0; i < total_th; i++) 
    { 
     if(pthread_join(pt[i], NULL) != 0) 
      fprintf(stderr, "error in thread join\n"); 
    } 

    return(0); 
} 

/** 
* void* countLines(void * input) 
* @param input: the name of the file 
* @return NULL 
* count the number of lines for the specified file 
*/ 
void* countLines(void * input) 
{ 
    char* fileName = (char*) input; /* file name */ 
    int newLineCount = 0; /* a count of the new line character */ 
    int fd; /*file descriptor*/ 

    /* open file, if open fail print error message */ 
    if((fd = open(fileName, O_RDONLY)) == -1) 
    { 
     fprintf(stderr, "Can not open file - %s\n", fileName); 
     count_th++; 
     return NULL; 
    } 

    char buf[BUFLEN]; /* the buffer to be read */ 
    int lastRead; /* the number of characters read to buffer */ 

    /* read the file */ 
    while((lastRead = read(fd, buf, BUFLEN))) 
    { 
     /* detect error state */ 
     if(lastRead == -1) 
     { 
      fprintf(stderr, "error reading file %s!\n", fileName); 
      count_th++; 
      return NULL; 
     } 

     /* count the new line character */ 
     int i; 
     for(i = 0; i < lastRead; i++) 
     { 
      if(buf[i] == '\n') 
      { 
       newLineCount++; 
      } 
     } 
    } 

    printf("There are %d lines in %s\n", newLineCount, fileName); 

    close(fd); /* close file descriptor */ 
    pthread_exit(NULL); 
} 

/** 
* void error(const char*str) 
* @param str error message 
* print an error message 
*/ 
void error(const char *str) 
{ 
    perror(str); 
    exit(-1); 
} 

ここでは、プログラムを実行するときのvalgrindの出力を示します。メモリリークは、未使用のスレッドを作成する関数からのものです。 時々このメッセージが表示されますが、時には表示されません。

==4737== 
==4737== HEAP SUMMARY: 
==4737==  in use at exit: 1,590 bytes in 5 blocks 
==4737== total heap usage: 12 allocs, 7 frees, 3,494 bytes allocated 
==4737== 
==4737== 36 bytes in 1 blocks are still reachable in loss record 1 of 5 
==4737== at 0x4C28F9F: malloc (vg_replace_malloc.c:236) 
==4737== by 0x40085BF: _dl_map_object (dl-load.c:162) 
==4737== by 0x4012B79: dl_open_worker (dl-open.c:226) 
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178) 
==4737== by 0x40133A9: _dl_open (dl-open.c:569) 
==4737== by 0x516AF6F: do_dlopen (dl-libc.c:86) 
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178) 
==4737== by 0x516B029: __libc_dlopen_mode (dl-libc.c:47) 
==4737== by 0x4E3F75B: pthread_cancel_init (unwind-forcedunwind.c:53) 
==4737== by 0x4E3F91B: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126) 
==4737== by 0x4E3D9DF: __pthread_unwind (unwind.c:130) 
==4737== by 0x4E380A4: pthread_exit (pthreadP.h:265) 
==4737== 
==4737== 36 bytes in 1 blocks are still reachable in loss record 2 of 5 
==4737== at 0x4C28F9F: malloc (vg_replace_malloc.c:236) 
==4737== by 0x400B43C: _dl_new_object (dl-object.c:164) 
==4737== by 0x4006575: _dl_map_object_from_fd (dl-load.c:967) 
==4737== by 0x400831E: _dl_map_object (dl-load.c:2260) 
==4737== by 0x4012B79: dl_open_worker (dl-open.c:226) 
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178) 
==4737== by 0x40133A9: _dl_open (dl-open.c:569) 
==4737== by 0x516AF6F: do_dlopen (dl-libc.c:86) 
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178) 
==4737== by 0x516B029: __libc_dlopen_mode (dl-libc.c:47) 
==4737== by 0x4E3F75B: pthread_cancel_init (unwind-forcedunwind.c:53) 
==4737== by 0x4E3F91B: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126) 
==4737== 
==4737== 56 bytes in 1 blocks are still reachable in loss record 3 of 5 
==4737== at 0x4C28F9F: malloc (vg_replace_malloc.c:236) 
==4737== by 0x400D187: _dl_map_object_deps (dl-deps.c:505) 
==4737== by 0x4012BD6: dl_open_worker (dl-open.c:263) 
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178) 
==4737== by 0x40133A9: _dl_open (dl-open.c:569) 
==4737== by 0x516AF6F: do_dlopen (dl-libc.c:86) 
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178) 
==4737== by 0x516B029: __libc_dlopen_mode (dl-libc.c:47) 
==4737== by 0x4E3F75B: pthread_cancel_init (unwind-forcedunwind.c:53) 
==4737== by 0x4E3F91B: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126) 
==4737== by 0x4E3D9DF: __pthread_unwind (unwind.c:130) 
==4737== by 0x4E380A4: pthread_exit (pthreadP.h:265) 
==4737== 
==4737== 288 bytes in 1 blocks are still reachable in loss record 4 of 5 
==4737== at 0x4C279F2: calloc (vg_replace_malloc.c:467) 
==4737== by 0x4010359: _dl_check_map_versions (dl-version.c:300) 
==4737== by 0x4012EF0: dl_open_worker (dl-open.c:269) 
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178) 
==4737== by 0x40133A9: _dl_open (dl-open.c:569) 
==4737== by 0x516AF6F: do_dlopen (dl-libc.c:86) 
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178) 
==4737== by 0x516B029: __libc_dlopen_mode (dl-libc.c:47) 
==4737== by 0x4E3F75B: pthread_cancel_init (unwind-forcedunwind.c:53) 
==4737== by 0x4E3F91B: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126) 
==4737== by 0x4E3D9DF: __pthread_unwind (unwind.c:130) 
==4737== by 0x4E380A4: pthread_exit (pthreadP.h:265) 
==4737== 
==4737== 1,174 bytes in 1 blocks are still reachable in loss record 5 of 5 
==4737== at 0x4C279F2: calloc (vg_replace_malloc.c:467) 
==4737== by 0x400B1CD: _dl_new_object (dl-object.c:77) 
==4737== by 0x4006575: _dl_map_object_from_fd (dl-load.c:967) 
==4737== by 0x400831E: _dl_map_object (dl-load.c:2260) 
==4737== by 0x4012B79: dl_open_worker (dl-open.c:226) 
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178) 
==4737== by 0x40133A9: _dl_open (dl-open.c:569) 
==4737== by 0x516AF6F: do_dlopen (dl-libc.c:86) 
==4737== by 0x400E9C5: _dl_catch_error (dl-error.c:178) 
==4737== by 0x516B029: __libc_dlopen_mode (dl-libc.c:47) 
==4737== by 0x4E3F75B: pthread_cancel_init (unwind-forcedunwind.c:53) 
==4737== by 0x4E3F91B: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126) 
==4737== 
==4737== LEAK SUMMARY: 
==4737== definitely lost: 0 bytes in 0 blocks 
==4737== indirectly lost: 0 bytes in 0 blocks 
==4737==  possibly lost: 0 bytes in 0 blocks 
==4737== still reachable: 1,590 bytes in 5 blocks 
==4737==   suppressed: 0 bytes in 0 blocks 
==4737== 
==4737== For counts of detected and suppressed errors, rerun with: -v 
==4737== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4) 
+1

*何が正確にメモリをリークしているのですか?すべてのスレッドを使用していないという意味ですか? – Chris

+0

あなたの配列に正確に何を保存していますか? (私はあなたが何か他のものよりむしろ早すぎると感じている) – sarnold

+0

valgrindがリークメッセージを出力するので、自分のプログラムがメモリをリークしていることが分かります。サンプルのコードスニペットが示すように、私は2つのスレッドを作成して結合しませんでした。それはメモリリークになります。 – xinghua

答えて

2

pthread_exitの「問題」です。 This questionは、具体的には、いくつかの詳細を与える:

いくつかglibcの機能は、それらがプロセスの有効期間の残りのために割り当てられ続けるのmalloc()は、それらが呼び出されている最初の時間とメモリを割り当てます。 glibcはプロセスの終了時にこのメモリを解放することはありません。なぜならプロセスが途中で切断されていることがわかっているからです.CPUサイクルの浪費にすぎません。

このメモリリークは問題ありません。あなただけの開始ルーチンから戻ってきているので、

しかし、実際にはvalgrindのメッセージを取り除くために、あなたは、countLinesの最後の行にpthread_exit(NULL);の代わりにreturn NULL;を使用することができます。

+0

ありがとうございました!私は最終的にそれを修正する。 – xinghua

関連する問題