Я создал массив потоков, но я не использую их все. это оказывается утечка памяти. Есть ли какая-нибудь функция, которую я мог бы использовать, чтобы освободить память?
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-check = полный --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)