tetraquark.ru_pthread_bug_2

Утечка памяти pthread?

Меня давно мучает одна интересная особенность при работе с pthread. Когда начинал работать с pthread, нужно было найти утечку памяти в небольшой программке. Использовал mtrace. Что не освобождал — нашел и исправил. Но была обнаружена еще одна утечка — пять плюсов, на которых как раз не хватало несколько минусов (см. mtrace()). Как бы я не пытался исправлять код, избавлялся от динамических массивов — эти пять плюсов все равно присутствовали в логах mtrace.
Когда писал пост про pthread в этот блог, данные плюсы снова у меня всплыли и начали снова мозолить мне глаза. Для начала, давайте посмотрим, что происходит.

Возьмем следующий код, который запускает 5 потоков, которые выводят в консоль простую строчку и завершают свою работу. Под идентификаторы потоков делаем массив threads. Также для примера создадим целочисленный массив arr на 10 элементов, чтобы просто было видно в mtrace как он очищается.

Следует обратить внимание, что потоки завершаются с помощью функции pthread_exit(0). Собственно ниже приведен результат выполнения данной программки и вывод лога mtrace.

tetraquark.ru_pthread_bug_1

Желтым вопросом на картинке помечены те странные строчки. Как видно, память, которая явно выделяется функцией malloc, отлично очищается, как и память, которая выделяется под потоки. Теперь попробуем увеличить количество потоков до 8 (#define N 8) — посмотрим, как поведут себя те загадочные 5 строчек.

tetraquark.ru_pthread_bug_3

Как видно на картинке сверху, количество неочищенной памяти не увеличилось. Можно сделать вывод, что с увеличением количества потоков память не течет (проверял на 100, тот же результат). Возможно, это баг mtrace, а может быть это и не баг вовсе. Также я попробовал проверить программу с 8 потоками на утечку с помощью Valgrind, вот результат:

tetraquark.ru_pthread_bug_5

Valgrind утечку, насколько я понимаю, вообще не обнаружил, что больше наводит на мысль, что это явление не баг.
Методом комментирования всего подряд я нашел очень простой и банальный вариант решения, который избавляет программу от этого проблемного выделения памяти. Я заменил функцию pthread_exit(0) для завершения потока на return 0. Результат приведен ниже (для 5 потоков):

tetraquark.ru_pthread_bug_2

Как видно — ничего лишнего.

Что в итоге это значит, я так и не могу понять, поэтому если знающий человек это читает, буду очень признателен, если этот знающий человек объяснит — почему так и ответит в комментариях.

Однозначного ответа на этот вопрос я так найти и не смог. Но пару интересных ссылок обнаружить удалось, где некоторые господа сообщают о том, что это явление — особенность реализации библиотеки glibc и что это не утечка. Данная память не освобождается сразу по завершению процесса программы, что в результате и было обнаружено. Ниже приведу две ссылки на обсуждения этого вопроса:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">