Допустимо ли что-то вроде этого:
std::vector<std::vector<int>> data;
std::shared_mutex m;
...
void Resize() {
// AreAllVectorsEmpty: std::all_of(data.begin(), data.end(), [](auto& v) { return v.empty(); }
if (!AreAllVectorsEmpty()) {
m.lock();
if (!AreAllVectorsEmpty()) {
data.resize(new_size);
}
m.unlock();
}
}
Я проверяю AreAllVectosEmpty()
, а затем, если условие успешно выполняется, затем берется блокировка, а затем снова проверяют то же условие, выполнять ли изменение размера.
Будет ли это потокобезопасным?Resize
вызывается только одним потоком, но другие потоки манипулируют элементами data
.
Требуется ли AreAllVectorsEmpty
иметь ограничение памяти или приобретать семантику?
Редактировать:Другие потоки будут блокироваться, когда m.lock
будет получен Resize
.
Редактировать: Предположим также, что new_size
достаточно велик для перераспределения.
Редактировать: Обновить код для shared_mutex.
Редактировать: AreAllVectorsEmtpy
выполняет итерацию по вектору данных.Никто другой не изменяет вектор данных, но данные [0], данные [1] и т. Д. Изменяются другими потоками.Мое предположение состоит в том, что переменная размера data [0] находится внутри вектора и представляет собой простое целое число, поэтому безопасно обращаться к data [0] .size (), data [1] .size () и т. Д. ВResize
нить.AreAllVectorsEmpty
перебирает data
и проверяет vector.empty()
.