Przeczytałem on Stackoverflow, że żaden z pojemników STL nie jest bezpieczny w użyciu dla pisania. Ale co to oznacza w praktyce? Czy to oznacza, że powinienem przechowywać zapisywalne dane w zwykłych tablicach?Bezpieczeństwo wątków pisania std :: vector vs plain array
Spodziewam się, że jednoczesne wywołania do std::vector::push_back(element)
mogą prowadzić do niespójnych struktur danych, ponieważ może to pociągać za sobą zmianę rozmiaru wektora. Ale co o takim wypadku, w którym zmiana rozmiaru nie jest zaangażowany:
1) za pomocą tablicy:
int data[n];
// initialize values here...
#pragma omp parallel for
for (int i = 0; i < n; ++i) {
data[i] += func(i);
}
2) przy użyciu `std :: vector``:
std::vector<int> data;
data.resize(n);
// initialize values here...
#pragma omp parallel for
for (int i = 0; i < n; ++i) {
data[i] += func(i);
}
Czy pierwsza implementacja jest naprawdę lepsza od drugiej: a) pod względem bezpieczeństwa gwintów i b) pod względem wydajności? Wolałbym używać std :: vector, ponieważ mniej mi się podobają tablice w stylu C.
EDYCJA: Usunąłem #pragma omp atomic update
chroniącego zapis.
Nie jestem wystarczająco pewny, aby zrobić odpowiedź, ale jestem pewien, że pisanie do różnych elementów 'std :: vector' jest wątkowo bezpieczne. – Angew
Te dwa fragmenty są równie bezpieczne dla wątków. –
"Ale co to oznacza w praktyce?" : Oznacza to, że pojemnik musi być zatrzaśnięty wyłącznie dla zapisu * i * odczytu, jeśli dowolna/każda operacja jest zbieżna z równoczesnym ** zapisaniem **. Możesz kazać wszystkim czytelnikom walić w pojemnik, który chcesz, ale jak tylko zostanie wprowadzony potencjał * zapisu, wszystkie zakłady są wyłączone i musisz zablokować * dostęp do wszystkich * (nie tylko innych autorów). Blokada z pojedynczym zapisem i wieloma odczytami działa dobrze w tym przypadku. – WhozCraig