Локальное хранилище Thread позволяет многопоточным приложениям иметь отдельный экземпляр данного элемента данных для каждого потока. Если однопоточное приложение будет использовать статические или глобальные данные, это может привести к спорам, тупику или повреждению данных в многопоточном приложении. Одним из примеров является переменная C<errno>, используемая для хранения кода ошибки, связанного с функциями из библиотеки Standard C. Это обычная практика (и требуется POSIX) для компиляторов, которые поддерживают многопоточные приложения, чтобы обеспечить отдельный экземпляр<errno>для каждого потока, чтобы избежать различных потоков, конкурирующих для чтения или обновления значения.
Хотя компиляторы часто предоставляют эту возможность в виде расширений синтаксиса деклараций (например, аннотации<__declspec(thread)>или<thread>на<static>или объявления переменных пространства имен), такая поддержка не является переносимой и часто ограничена каким-либо образом, например, только поддерживающими типами POD.
<boost::thread_specific_ptr>обеспечивает переносной механизм для хранения потоков, который работает на всех компиляторах, поддерживаемых.Подъем.Подъем. Каждый экземпляр<boost::thread_specific_ptr>представляет собой указатель на объект (например,<errno>), где каждая нить должна иметь различное значение. Значение для текущего потока может быть получено с помощью функции<get()>члена или с помощью операторов<*>и<->>отсчета указателей. Первоначально указатель имеет значение<NULL>в каждом потоке, но значение для текущего потока может быть установлено с помощью функции члена<reset()>.
Если значение указателя для текущей нити изменяется с помощью<reset()>, то предыдущее значение разрушается путем вызова процедуры очистки. Альтернативно, сохраненное значение может быть сброшено до<NULL>, а предыдущее значение возвращено вызовом функции<release()>, что позволяет приложению взять на себя ответственность за уничтожение объекта.
При выходе нити уничтожаются предметы, связанные с каждым<boost::thread_specific_ptr>экземпляром. По умолчанию объект, на который указывает указатель<p>, разрушается путем вызова<deletep>, но это может быть отменено для конкретного примера<boost::thread_specific_ptr>, обеспечивая рутину очистки конструктору. В этом случае объект разрушается путем вызова<func(p)>, где<func>- это процедура очистки, подаваемая конструктору. Функции очистки называются в неуказанном порядке. Если процедура очистки устанавливает значение, связанное с экземпляром<boost::thread_specific_ptr>, который уже был очищен, это значение добавляется в список очистки. Очистка заканчивается, когда нет выдающихся примеров<boost::thread_specific_ptr>с ценностями.
Примечание: на некоторых платформах очистка потоковых данных не выполняется для потоков, созданных с помощью собственного API платформы. На этих платформах такая очистка производится только для потоков, которые начинаются с<boost::thread>, если<boost::on_thread_exit()>не называется вручную из этой нити.
Повышаю. Thread использует адрес экземпляра<thread_specific_ptr>в качестве ключа конкретных указателей потока. Это позволяет избежать создания/уничтожения ключа, который будет нуждаться в замке для защиты от условий гонки. Это имеет небольшую ответственность за производительность, так как доступ должен быть выполнен с использованием ассоциативного контейнера.
namespace boost
{
template <typename T>
class thread_specific_ptr
{
public:
thread_specific_ptr();
explicit thread_specific_ptr(void (*cleanup_function)(T*));
~thread_specific_ptr();
T* get() const;
T* operator->() const;
T& operator*() const;
T* release();
void reset(T* new_value=0);
};
}
- Requires:
<deletethis->get()>Хорошо сформирован.
- Effects:
Постройте<thread_specific_ptr>объект для хранения указателя на объект типа<T>, специфичный для каждой нити. Функция очистки по умолчанию<delete>будет использоваться для уничтожения любых потоковых объектов, когда<reset()>называется, или поток выходит.
- Throws:
<boost::thread_resource_error>Если произошла ошибка.
- Requires:
<cleanup_function(this->get())>Никаких исключений.
- Effects:
Постройте<thread_specific_ptr>объект для хранения указателя на объект типа<T>, специфичный для каждой нити. Поставляемые<cleanup_function>будут использоваться для уничтожения любых нитей-местных объектов, когда<reset()>называется, или нитей выходит.
- Throws:
<boost::thread_resource_error>Если произошла ошибка.
- Requires:
Все конкретные экземпляры потока, связанные с этим потоком_specific_ptr (за исключением, возможно, одного, связанного с этим потоком), должны быть нулевыми.
- Effects:
Призывает<this->reset()>очистить связанное значение для текущей нити и разрушает<*this>.
- Throws:
Ничего.
- Remarks:
Требование обусловлено тем, что для удаления всех этих экземпляров реализация должна быть вынуждена поддерживать список всех потоков, имеющих ассоциированный конкретный ptr, что противоречит цели потока конкретных данных.
![[Note]](/img/note.png) |
Note |
Необходимо позаботиться о том, чтобы любые потоки, все еще работающие после того, как экземпляр<boost::thread_specific_ptr>был уничтожен, не вызывали никаких функций участника на этом экземпляре. |
- Returns:
Указатель, связанный с текущей нитью.
- Throws:
Ничего.
![[Note]](/img/note.png) |
Note |
Начальное значение, связанное с экземпляром<boost::thread_specific_ptr>, составляет<NULL>для каждой нити. |
- Returns:
<this->get()>
- Throws:
Ничего.
- Requires:
<this->get>не является<NULL>.
- Returns:
<*(this->get())>
- Throws:
Ничего.
- Effects:
Если<this->get()!=new_value>и<this->get()>не являются<NULL>, ссылайтесь<deletethis->get()>или<cleanup_function(this->get())>соответственно. Храните<new_value>как указатель, связанный с текущей нитью.
- Postcondition:
<this->get()==new_value>
- Throws:
<boost::thread_resource_error>Если произошла ошибка.
- Effects:
Возврат<this->get()>и хранение<NULL>в качестве указателя, связанного с текущей нитью, без вызова функции очистки.
- Postcondition:
<this->get()==0>
- Throws:
Ничего.