Использование параллельных расширений с атрибутом ThreadStatic. Может ли это утечка памяти?
Я использую Parallel Extensions довольно интенсивно, и я только что столкнулся со случаем, когда использование локального хранилища потоков может быть целесообразным, чтобы разрешить повторное использование объектов рабочими потоками. Поэтому я смотрел на атрибут ThreadStatic, который помечает статическое поле / переменную как имеющее уникальное значение для каждого потока.
Мне кажется, что было бы неразумно использовать PE с атрибутом ThreadStatic без какой-либо гарантии повторного использования потока PE. То есть, если потоки создаются и уничтожаются до некоторой степени, будут ли переменные (и, следовательно, объекты, на которые они указывают) оставаться в локальном хранилище потоков в течение некоторого неопределенного периода времени, вызывая тем самым утечку памяти? Или, возможно, хранилище потоков привязано к потокам и утилизируется, когда потоки располагаются? Но тогда у вас все еще потенциально есть потоки в пуле с долгим сроком службы, которые накапливают локальное хранилище потоков из различных фрагментов кода, для которых используются потоки.
Есть ли лучший подход к получению потокового локального хранилища с помощью PE?
Спасибо.
2 ответа
Я настоятельно рекомендую использовать обычный шаблон для локального хранилища потоков, описанный в этой статье MSDN.
Когда вы используете [ThreadStatic], имеет значение, очищает ли поток пула потоков переменные TLS, когда он завершается. В документах MSDN нет никаких указаний на то, что это не так. Это не сложно реализовать, нужно только вызвать функцию API TlsFree (). Я написал небольшое тестовое приложение, никаких признаков утечки.
РЕДАКТИРОВАТЬ: Учитывая ответ Ганса, похоже, что TLS на самом деле будет очищен в любом случае... который просто оставляет этот бит ответа:
У вас действительно нет лучшего способа повторно использовать значения в потоке? Если есть две задачи, использующие один и тот же поток (одна завершается, а другая выполняется), действительно ли они захотят получить одно и то же значение? Вы на самом деле просто используете это как способ избежать более контролируемого распространения данных в вашей задаче?