2016-11-11 1 views
2

Есть ли преимущества в объявлении std::vector как thread_local? какКогда кто-то определит std :: vector как thread_local?

static unique_ptr<std::vector<ObjectA>> vecVariable; 

как объявление std::vector, как thread_local не делает свою работу, как и pop_back()erase() синхронизированы.

Как и в любой STL контейнер, если есть одна нить модификации контейнера, то не должно быть никаких параллельных потоков чтения или записи и тот же контейнер, так что я не могу сделать erase() и pop_back() на vector объекта в параллельной/многопоточной среде ,

Даже если я объявляю вектор thread_local, мой код разбивается на одну из операций. Я понимаю, что мне может понадобиться делать эти операции под замком, но я просто пытаюсь понять, когда кто-то определит std::vector как thread_local?

+0

В то же время они определяли бы любую переменную как thread_local - когда каждый поток должен иметь свой собственный экземпляр. – davmac

ответ

4

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

Вы должны объявить переменную vector или любую другую переменную thread_local, если вы хотите, чтобы каждый поток имел свой собственный экземпляр переменной. Если вы хотите иметь доступ к одному объекту одновременно, решение не объявлять его thread_local, а вместо этого использовать потокобезопасный тип данных или соответствующие примитивы синхронизации (например, путем блокировки и разблокировки std::mutex).

+0

@ GillBates каждый поток _can_ доступ к копии, принадлежащей другим потокам, если он может получить ссылку на них другими способами. То, что имя относится к различным объектам в разных потоках, не подразумевает безопасности потоков. – davmac

+0

Конечно, они могут через адресацию или глобальные ссылки. Я говорил о случае использования имени и только имени. –

+0

Как я уже сказал, нет необходимости заботиться о безопасности потоков в первую очередь при доступе к элементам в этом векторе через его имя, например. 'Вектор [0]'. Ключевое слово само по себе не приносит никакой синхронизации, но при правильном использовании избегает скачков данных между потоками, если потоки не полагаются на другие потоки, чтобы заполнить или изменить этот контейнер. –

5

thread_local не предназначен для синхронизации. Это означает, как продолжительность хранения спецификатора (http://en.cppreference.com/w/cpp/language/storage_duration)

Возьмем такой пример:

#include <iostream> 
#include <vector> 
#include <thread> 

thread_local std::vector<int> v; 

void func() 
{ 
    v.push_back(5); 
    std::cout<< "t: "<< v.size() << std::endl; 
} 

int main() 
{ 
    v.push_back(3); 
    v.push_back(5); 
    std::thread t1(func); 
    std::thread t2(func); 
    std::cout<< "m: "<< v.size() << std::endl; 
    t1.join(); 
    t2.join(); 
} 

выход:

m: 2 
t: 1 
t: 1 

Что thread_local делает это создать другой вектор для каждого потока. В примере вы можете видеть, что v из основного потока имеет 2 элемента, а вектор v в других потоках имеет только по 1 элемент.

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

Смежные вопросы