Назад к вопросам
Middle
182
questionbank
Является ли std::shared_ptr потокобезопасным?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Нет. std::shared_ptr потокобезопасен для одновременного доступа к управляющему блоку (increment/decrement счетчика ссылок), но не для доступа к объекту, на который он указывает. Несколько потоков могут безопасно увеличивать или уменьшать счетчик ссылок одного std::shared_ptr одновременно. Однако, одновременный доступ к самому объекту, которым управляет std::shared_ptr, требует внешних механизмов синхронизации, таких как мьютексы.
Пример:
#include <iostream>
#include <memory>
#include <vector>
#include <thread>
#include <mutex>
struct Data {
int value;
std::mutex mutex; // Добавляем мьютекс для синхронизации доступа к value
};
int main() {
auto shared_data = std::make_shared<Data>();
// Небезопасно: несколько потоков одновременно пишут в shared_data->value без синхронизации
// auto unsafe_access = [&](int id) {
// for (int i = 0; i < 1000; ++i) {
// shared_data->value++;
// }
// };
// Безопасно: используем мьютекс для защиты доступа к shared_data->value
auto safe_access = [&](int id) {
for (int i = 0; i < 1000; ++i) {
std::lock_guard<std::mutex> lock(shared_data->mutex); // Захват мьютекса
shared_data->value++;
}
};
std::vector<std::thread> threads;
for (int i = 0; i < 10; ++i) {
threads.emplace_back(safe_access, i);
// threads.emplace_back(unsafe_access, i); // Для демонстрации небезопасного доступа
}
for (auto& t : threads) {
t.join();
}
std::cout << "Final value (safe): " << shared_data->value << std::endl; // Предполагаемое значение 10000
// Если использовать unsafe_access, итоговое значение будет, скорее всего, меньше 10000
// std::cout << "Final value (unsafe): " << shared_data->value << std::endl;
return 0;
}