Проверьте, является ли нить бустерной - PullRequest
4 голосов
/ 24 января 2011

В целях локальной очистки потока мне нужно создать утверждение, которое проверяет, был ли текущий поток создан с помощью boost :: thread.Как я могу проверить, было ли это так?То есть, как я могу проверить, обрабатывается ли текущий поток boost :: thread?

Мне просто нужно это сделать, чтобы очистить локальное хранилище потока, когда поток завершается.Boost's thread_local_ptr, по-видимому, работает только в том случае, если сам поток является вспомогательным потоком.

Обратите внимание, что я не делаю проверку во время очистки, а иногда в течение срока службы потока.Некоторые функции вызывают один из наших API / обратных вызовов (косвенно), заставляя меня выделять локальное хранилище потока.Это разрешено делать только потокам ускорения, поэтому в этот момент мне нужно определить, не является ли поток ускорением.


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


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

Ответы [ 3 ]

3 голосов
/ 25 января 2011

Предпосылка для вашего вопроса ошибочна :) boost :: thread_specific_ptr работает, даже если поток не является потоком Boost.Подумайте об этом - как будет работать конкретное хранилище для основного потока, поскольку невозможно создать его с помощью boost?Я прекрасно использовал boost :: thread_specific_ptr из основного потока, и хотя я не изучал реализацию boost :: thread_specific_ptr, наиболее очевидный способ его реализации сработал бы даже для потоков без поддержки.Большинство операционных систем позволяют вам получить уникальный идентификационный номер для текущего потока, который затем можно использовать в качестве индекса в карте / массиве / хеш-таблице.

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

0 голосов
/ 25 января 2011

Каждый раз, когда заканчивается поток поддержки, все Специфичные данные потока очищаются.TSD это указатель, вызывающий delete p* при уничтожении / сбросе.

При желании вместо delete p* может вызываться обработчик очистки для каждого элемента.Этот обработчик указан в конструкторе TLS, и вы можете использовать функцию очистки, чтобы выполнить однократную очистку.

#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/thread/tss.hpp>

void cleanup(int* _ignored) {
    std::cout << "TLS cleanup" << std::endl;
}

void thread_func() {
    boost::thread_specific_ptr<int> x(cleanup);
    x.reset((int*)1); // Force cleanup to be called on this thread

    std::cout << "Thread begin" << std::endl;
}

int main(int argc, char** argv) {
    boost::thread::thread t(thread_func);

    t.join();

    return 0;
}
0 голосов
/ 25 января 2011

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

Предполагая, что вы имеете в виду проверку во время выполнения:

Есливы не смешиваете boost::thread с другими методами, тогда проблема просто исчезнет.Любые библиотеки, которые создают потоки, должны уже иметь дело со своими собственными потоками автоматически (или для функции завершения работы с API-документами, которые вы должны вызывать).

В противном случае вы можете оставить, например, контейнер всех * 1008.* s вы создаете без использования boost::thread и проверяете, находится ли нить в контейнере при завершении работы.Если его нет в контейнере, то он был создан с использованием boost::thread.

РЕДАКТИРОВАТЬ: вместо того, чтобы пытаться определить, было ли оно создано с помощью boost::thread, вы рассмотрели настройку приложения, чтобы обратный вызов API могвстречаются только в темах, созданных с помощью boost::thread?Таким образом вы заранее решаете проблему и устраняете необходимость проверки, которую, если она вообще существует, было бы болезненно реализовать.

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