Возможна ли активная инициализация thread_local в C ++? - PullRequest
0 голосов
/ 11 октября 2018

[basic.stc.thread] гласит, что «переменная с продолжительностью хранения потока должна быть инициализирована до ее первого использования odr (6.2) и, если она создана, должна быть уничтожена при выходе из потока».

Разве это исключает реализацию, инициализирующую переменную области имен thread_local с нетерпением при создании потока, и поддерживают ли какие-либо крупные компиляторы какой-либо механизм, чтобы принудительно сделать это через некоторую аннотацию?

У меня оченьнебольшое количество критичных к производительности __thread переменных. Я бы хотел не использовать ленивые проверки инициализации для каждого доступа, которые обычно выполняются thread_local, но в настоящее время мне нужно выполнить настройку / разборку через отдельные вызовы, чтобы остаться в пределах __thread ограничения на нетривиальные деструкторы и т. д. Могу ли я получить thread_local с гарантированной энергичной конструкцией / разрушением для каждого потока и без ленивого тестирования инициализации?

В противном случае, каков самый чистый из известных шаблонов для работы с __thread настройка / отмена регистрации звонка?

1 Ответ

0 голосов
/ 11 октября 2018

Могу ли я получить thread_local с гарантированной энергичной конструкцией / разрушением для каждого потока и без ленивого тестирования инициализации?

Маловероятно.

В противном случае,Какой самый чистый из известных шаблонов для работы с __thread регистрацией вызова установки / разрыва?

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

struct ThreadContext {
    thread_local static ThreadContext* instance;

    ThreadContext() {
        assert(!instance);
        instance = this;
    }

    ~ThreadContext() {
        instance = 0;
    }

    ThreadContext(ThreadContext const&) = delete;
    ThreadContext& operator=(ThreadContext const&) = delete;
};

thread_local ThreadContext* ThreadContext::instance = 0;

void thread_function() {
    ThreadContext context;

    // Access it elsewhere as:
    ThreadContext::instance;  
}

ThreadContext* getThisThreadContext() {
    return ThreadContext::instance;  
    // No init check here. Just one move:
    // mov rax, QWORD PTR fs:ThreadContext::instance@tpoff
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...