LINUX.ORG.RU

pthread: утечка памяти или нормальная работа?


0

0

Доброго времени суток! есть такая тестовая программа


#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

void* test_thread(void* arg);
extern int pthread_create (pthread_t *__restrict __newthread,
			   __const pthread_attr_t *__restrict __attr,
			   void *(*__start_routine) (void *),
			   void *__restrict __arg) __THROW __nonnull ((1, 3));
extern int pthread_cancel (pthread_t __th);

int main(int argc, char** argv) {
    pthread_t thread_id;
    pthread_t thread_id_array[1000];
    int err = 0;
    pthread_attr_t pthread_attr;
    int i = 0;
    char* ch=NULL;

    if ((err = pthread_attr_init(&pthread_attr)) != 0) {
        printf("pthread_attr_init() ERROR: %s\n", strerror(errno));
    }

    if ((err = pthread_attr_setdetachstate(&pthread_attr, PTHREAD_CREATE_DETACHED)) != 0) {
        printf("pthread_attr_init() ERROR: %s\n", strerror(errno));
    }

    printf("потоков нет, press any key \n");
    getc(stdin); //ждем ввода
    
    for (i = 0; i < 100; i++) { //создаем 1000 потоков
        if ((err = pthread_create(&thread_id,
                &pthread_attr,
                &test_thread,
                NULL)) != 0) //создаем новый поток и передаем в него указатель на функцию connection_thread
        {
            printf("pthread_attr_init() ERROR: can't create connection thread: %s\n", strerror(err));
        }
        printf("%i\n", i);
        thread_id_array[i] = thread_id;
        //sleep(1);
    }

    printf("100 потоков создано, press any key \n");
    getc(stdin); //ждем ввода

    for (i = 49; i < 100; i++) { //закрываем 1000 потоков
        if ((err = pthread_cancel(thread_id_array[i])) != 0) //создаем новый поток и передаем в него указатель на функцию connection_thread
        {
            printf("%i\n", i);
            printf("pthread_cancel() ERROR: can't create connection thread: %s\n", strerror(err));
        }
    }
    printf("50 потоков закрыто, press any key \n");
    getc(stdin); //ждем ввода

    for (i = 49; i < 100; i++) { //создаем 500 потоков
        if ((err = pthread_create(&thread_id,
                &pthread_attr,
                &test_thread,
                NULL)) != 0) //создаем новый поток и передаем в него указатель на функцию connection_thread
        {
            printf("pthread_attr_init() ERROR: can't create connection thread: %s\n", strerror(err));
        }
        printf("%i\n", i);
        thread_id_array[i] = thread_id;
    }

    printf("50 потоков создано, press any key \n");
    getc(stdin); //ждем ввода

    return EXIT_SUCCESS;
}

void* test_thread(void* arg) {
    sleep(3600); //час
    /*
        int i = 0;
        int j = 0;
        for (i = 0; i < 100000; i++) {
            j = i;
        }
     */
    //printf("pthread_attr_init() ERROR: can't create connection thread: %s\n", strerror(err));
    return;
}

так вот, если запустить ее под valgring memcheck:

==9843== Memcheck, a memory error detector
==9843== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==9843== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for copyright info
==9843== Command: ./threadtest
==9843== Parent PID: 8218
==9843== 
==9843== 
==9843== HEAP SUMMARY:
==9843==     in use at exit: 13,600 bytes in 100 blocks
==9843==   total heap usage: 152 allocs, 52 frees, 20,924 bytes allocated
==9843== 
==9843== 6,392 bytes in 47 blocks are possibly lost in loss record 1 of 2
==9843==    at 0x4023F5B: calloc (vg_replace_malloc.c:418)
==9843==    by 0x40109AB: _dl_allocate_tls (dl-tls.c:300)
==9843==    by 0x4046102: pthread_create@@GLIBC_2.1 (allocatestack.c:561)
==9843==    by 0x8048969: main (main.c:68)
==9843== 
==9843== 7,208 bytes in 53 blocks are possibly lost in loss record 2 of 2
==9843==    at 0x4023F5B: calloc (vg_replace_malloc.c:418)
==9843==    by 0x40109AB: _dl_allocate_tls (dl-tls.c:300)
==9843==    by 0x4046102: pthread_create@@GLIBC_2.1 (allocatestack.c:561)
==9843==    by 0x8048811: main (main.c:42)
==9843== 
==9843== LEAK SUMMARY:
==9843==    definitely lost: 0 bytes in 0 blocks
==9843==    indirectly lost: 0 bytes in 0 blocks
==9843==      possibly lost: 13,600 bytes in 100 blocks
==9843==    still reachable: 0 bytes in 0 blocks
==9843==         suppressed: 0 bytes in 0 blocks
==9843== 
==9843== For counts of detected and suppressed errors, rerun with: -v
==9843== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 17 from 10)

если посмотреть выделение памяти в программе с помощью top, то память, занимаемая после создания 50 потоков(в сумме 100) больше, чем начальное значение при 100 потоках. Я ожидал, что память при начальном создании 100 потоков и после закрытия -создания 50 потоков(в сумме 100) будет одинаковым. Вроде, делаю все правильно, почему такое происходит с памятью? Или так и должно быть?

Создай их без PTHREAD_CREATE_DETACHED, вызови pthread_join, и посмотри, есть ли утечка.

tailgunner ★★★★★
()

Кажется это связано с резервированием памяти под стек потока. После завершения потока память не отдается системе, а используется при создании следующего потока. Так что это не совсем утечка.

anonymous
()

надо бы вам арифметику подтянуть.

anonymous
()

Какую колонку в top смотришь?
На мой взгляд, все в этой программе корректно. Попробуй вызвать malloc_stats.

goose
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.