Использование
std::mutex в качестве локальной переменной может привести к различным проблемам, особенно если он используется для синхронизации доступа к общим данным. Локальный std::mutex будет уничтожен при выходе из области видимости, что нарушит работу других потоков, ожидающих блокировку или разблокировку.🚩Проблемы с локальным `std::mutex`
🟠Жизненный цикл локального `std::mutex`
Локальная переменная уничтожается при выходе из функции или блока, в котором она объявлена. Это может привести к неопределенному поведению, если другие потоки все еще используют этот мьютекс.
🟠Неопределенное поведение
Уничтожение мьютекса, который все еще заблокирован, может привести к неопределенному поведению программы и потенциальным сбоям.
🚩Решение проблемы
Чтобы исправить проблему, нужно гарантировать, что
std::mutex имеет более длительный срок жизни и доступен всем потокам, которые его используют.🚩Правильные подходы
🟠Использование глобального или статического мьютекса
Если мьютекс используется для защиты глобальных или статических данных, сделайте его также глобальным или статическим.
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void sharedFunction() {
std::lock_guard<std::mutex> lock(mtx);
// Доступ к общим данным
std::cout << "Thread " << std::this_thread::get_id() << " is running\n";
}
int main() {
std::thread t1(sharedFunction);
std::thread t2(sharedFunction);
t1.join();
t2.join();
return 0;
}
🟠Член класса
Если мьютекс используется для защиты данных объекта, объявите его членом класса.
#include <iostream>
#include <thread>
#include <mutex>
class SharedResource {
private:
std::mutex mtx;
int data;
public:
void increment() {
std::lock_guard<std::mutex> lock(mtx);
++data;
std::cout << "Data: " << data << " from thread " << std::this_thread::get_id() << "\n";
}
};
int main() {
SharedResource resource;
std::thread t1(&SharedResource::increment, &resource);
std::thread t2(&SharedResource::increment, &resource);
t1.join();
t2.join();
return 0;
}
🟠Использование умных указателей
Если мьютекс должен иметь динамическую продолжительность жизни, используйте умные указатели, такие как
std::shared_ptr или std::unique_ptr. #include <iostream>
#include <thread>
#include <mutex>
#include <memory>
void sharedFunction(std::shared_ptr<std::mutex> mtx) {
std::lock_guard<std::mutex> lock(*mtx);
// Доступ к общим данным
std::cout << "Thread " << std::this_thread::get_id() << " is running\n";
}
int main() {
auto mtx = std::make_shared<std::mutex>();
std::thread t1(sharedFunction, mtx);
std::thread t2(sharedFunction, mtx);
t1.join();
t2.join();
return 0;
}
Ставь 👍 и забирай 📚 Базу знаний