Распределение и освобождение памяти между потоками - PullRequest
5 голосов
/ 24 декабря 2008

Я все еще пытаюсь отладить очень хитрую проблему повреждения памяти. Я наткнулся на раздел моего кода, который распределяет память в одном потоке и удаляет его в другом.

У меня смутное ощущение, что это неправильно, но я не уверен, почему. Потоки разделяют память процесса и доступ к этим структурам защищен мьютексом, поэтому я думаю, что все будет работать. Однако есть ли опасность, которую я не вижу?

Ответы [ 5 ]

5 голосов
/ 24 декабря 2008

Как указано в другом ответе @monjardin, нет ничего плохого в том, что вы пытаетесь сделать.

В качестве дополнительной мысли вы не упомянули платформу и т. Д., С которой вы столкнулись с этой проблемой, но если многопоточность является новой для вас и / или для этого приложения, над которым вы работаете, вы хотите быть уверены, что используемые вами стандартные библиотеки поддержки являются поточно-ориентированными версиями библиотек. Во многих средах / платформах они имеют как однопоточные, так и многопоточные версии библиотек поддержки, доступных разработчику. Если вы используете потоки, но ссылаетесь на однопотоковую версию библиотек, может случиться много плохих вещей. Например, в однопоточной библиотеке поддержки для malloc () и free () она не будет иметь мьютекс-защиту для кучи (как оптимизация). Многопоточная версия библиотеки добавит мьютекс-защиту к диспетчеру кучи для поддержки более чем одного потока, манипулирующего кучей одновременно. (Это только один пример).

1 голос
/ 24 декабря 2008

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

1 голос
/ 24 декабря 2008

Нет, это нормально, и довольно часто, особенно при программировании Windows с использованием CreateThread, где вы можете выделить аргументы в куче и передать аргумент в качестве аргумента void * в CreateThread. И самое простое, что нужно сделать, это позволить вызываемому потоку удалить его аргументы, когда он закончил с ними. Однако, если у вас есть проблемы с повреждением памяти, и вы обеспокоены тем, чтобы один поток удалял память, созданную другим, возможно, вам следует подумать о том, происходит ли двойное удаление, скажем, если передача того контекста теперь отвечает за очистку выделенного память не ясна, возможно, как вызывающий, так и вызываемый раздел делают это?

0 голосов
/ 24 декабря 2008

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

Есть ли вероятность, что какой-то код пытается получить доступ к этим структурам данных вне защиты мьютекса? Или, что еще хуже, может быть вероятность того, что некоторые из этих структур станут жертвами соображений времени жизни объектов C ++ (скажем, они разрушаются, потому что на них ссылаются с помощью boost :: shared_ptrs и последний shared_ptr только что вышел из здания?

Вы на 100% уверены, что это повреждение памяти? Другая ошибка, которая выглядит очень похожей, - это когда некоторый код удерживает ссылку, которой он не должен, и ссылочный объект перемещается из-за перераспределения памяти. Это не такой странный сценарий, поскольку добавление еще одного элемента в вектор может вызвать это (просто в качестве примера).

0 голосов
/ 24 декабря 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...