LINUX.ORG.RU

Асинхронное прерывание потока - возможна ли утечка памяти?

 , pthreadcancel, выделение памяти


1

2

Возник такой вопрос. Создаем поток, ставим ему режим PTHREAD_CANCEL_ASYNCHRONOYS. Далее где-то в потоке выделяем память char *buf = new char[100500];

Получается что возможна ситуация, когда посланная команда прерывания потока попадет между вызовом new и присвоением ее результата в переменную buf. Тогда получается память уже выделена, но улетаем в обработчик останова с мусором в buf - имеем утечку. Что-то я сомневаюсь что система/компилятор могут сами разруливать такое.

Возможна не только утечка, но и порча структур данных (та же самая куча во время malloc()) программы, файлов и т.п.

mashina ★★★★★
()
Ответ на: комментарий от mashina

цитата из man malloc

       Внутри   данных  функций  для  защиты  от  повреждений  выделяемых  структур  данных  управления  памятью,
       используются мьютексы. В многонитиевых приложениях, в которых нити  одновременно  выделяют  и  освобождают
       память,  может  возникнуть  конфликт  за  обладание  этими мьютексами. Чтобы расширить обработку выделения
       памяти  в  многонитиевых  приложениях  библиотека  glibc  создаёт  дополнительные  дополнительные  области
       выделения  памяти,  если  обнаруживается конфликт. Каждая область представляет собой большой кусок памяти,
       который внутренне выделен системой (с помощью  brk(2)  или  mmap(2))  и  управляется  своими  собственными
       мьютексами.

так что нет

Harald ★★★★★
()
Ответ на: комментарий от Harald

Там описывается случай разрешения локов во время одновременного выполнения malloc(). Если один из malloc()'ов не может захватить мьютекс основной арены (большой нарезанный на чанки кусок памяти), то он лезет в дополнительные арены (небольшие кусочки).

Это не имеет никакого относится к порчи структур данных во время прерывания операции в середине выполнения.

Ах да, минус тебе в карму за копипасту уродливого мана.

mashina ★★★★★
()
Ответ на: комментарий от mashina

если поток будет прибит при залоченном мьютексе, то мьютекс по идее останется залоченным, и программа в целом упасть от этого не должна

Harald ★★★★★
()

Ты бы хоть почитал про pthread'ы: pthread_cleanup_push/pop. А вообще многие, особоенно англо-саксоны всякие,советуют вручную проверять флажок завершения треда и самому обрабатывать прерывание в теле треда. Вообще, если ты не особо хорошо знаешь питреды, то уж луче используй флажки, вообще запретив иными способами прерывать треды. Это будет намного проще, надежней и даже не на много более костыльно, чем использовать питредовскую отмену, которая только недавно начала нормально под виндой работать.

maggotroot
()

Кури cancellation points. Есть строго определенный список функций, при вызове которых может остановиться нить, которой сделали cancel. Malloc не входит в их число.

kvap
()
Ответ на: комментарий от kvap

Ну как я понял cancellation points имеют смысл только в режиме PTHREAD_CANCEL_DEFERRED. Если же PTHREAD_CANCEL_ASYNCHRONOYS поставить, то в моем тесте cancel прерывал даже тупой while(1){}

KerHarrad
() автор топика
Ответ на: комментарий от KerHarrad

Зачем делать себе буратино? Поставь CANCEL_DEFERRED в начале этого куска кода, и CANCEL_ASYNCHRONOUS — в конце. Если хочется проблем, то можно придумать более простые способы.

kvap
()
Ответ на: комментарий от kvap

Да в принципе и только CANCEL_DEFERRED устроит. Сейчас вообще всё на флажках крутится (как тут выше советовали) - и нормал. Просто интересно стало как «по науке» сделать)

KerHarrad
() автор топика
Ответ на: комментарий от Harald

если поток будет прибит при залоченном мьютексе, то мьютекс по идее останется залоченным, и программа в целом упасть от этого не должна

Ок, мб упасть не должна. Но судя по коду, free() для блока из потерянной арены может сделать дедлок (зависит от опций сборки). Тоже можно считать порчей состояния.

А на realloc(), похоже, будет в дедлоке всегда.

mashina ★★★★★
()
Последнее исправление: mashina (всего исправлений: 1)

Получается что возможна ситуация, когда посланная команда прерывания потока попадет между вызовом new и присвоением ее результата в переменную buf.

От того, что тред успеет ее присвоить в buf, ситуация коренным образом не поменяется.

А какую роль играет этот тред, который надо прерывать?

ratatosk
()
Ответ на: комментарий от x905

сейчас борщевики набегут и скажут что кутэ не нужен/говно/etc.

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