В чем разница между семафором и мьютексом
1️⃣ Как кратко ответить
Семафор и мьютекс — это механизмы синхронизации в многопоточных приложениях. Мьютекс используется для обеспечения эксклюзивного доступа к ресурсу, позволяя только одному потоку владеть им в любой момент времени. Семафор может управлять доступом к ресурсу для нескольких потоков одновременно, позволяя ограниченное количество потоков использовать ресурс одновременно.
2️⃣ Подробное объяснение темы
В многопоточных приложениях часто возникает необходимость синхронизации доступа к общим ресурсам, чтобы избежать состояния гонки и других проблем, связанных с параллельным доступом. Для этого используются различные механизмы синхронизации, такие как семафоры и мьютексы.
Мьютекс
Мьютекс (от англ. "mutual exclusion" — взаимное исключение) — это примитив синхронизации, который позволяет только одному потоку владеть ресурсом в любой момент времени. Мьютекс используется, когда необходимо обеспечить эксклюзивный доступ к ресурсу, например, к переменной или файлу.
Пример использования мьютекса:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx; // Создаем мьютекс
void print_message(const std::string& message) {
mtx.lock(); // Захватываем мьютекс
std::cout << message << std::endl; // Критическая секция: выводим сообщение
mtx.unlock(); // Освобождаем мьютекс
}
int main() {
std::thread t1(print_message, "Hello from thread 1");
std::thread t2(print_message, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
std::mutex mtx;— создается объект мьютекса.mtx.lock();— поток захватывает мьютекс, получая эксклюзивный доступ к критической секции.std::cout << message << std::endl;— критическая секция, где выполняется работа с общим ресурсом.mtx.unlock();— поток освобождает мьютекс, позволяя другим потокам захватить его.
Семафор
Семафор — это более гибкий механизм синхронизации, который позволяет управлять доступом к ресурсу для нескольких потоков одновременно. Семафор имеет счетчик, который определяет, сколько потоков могут одновременно использовать ресурс. Семафоры бывают двух типов: бинарные (аналог мьютекса) и счетные (позволяют более чем одному потоку использовать ресурс).
Пример использования семафора:
#include <iostream>
#include <thread>
#include <semaphore.h>
std::counting_semaphore<3> sem(3); // Создаем счетный семафор с максимальным значением 3
void access_resource(int thread_id) {
sem.acquire(); // Захватываем семафор, уменьшая счетчик
std::cout << "Thread " << thread_id << " is accessing the resource." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1)); // Симулируем работу с ресурсом
sem.release(); // Освобождаем семафор, увеличивая счетчик
}
int main() {
std::thread t1(access_resource, 1);
std::thread t2(access_resource, 2);
std::thread t3(access_resource, 3);
std::thread t4(access_resource, 4);
t1.join();
t2.join();
t3.join();
t4.join();
return 0;
}
std::counting_semaphore<3> sem(3);— создается счетный семафор с максимальным значением 3, что позволяет трем потокам одновременно использовать ресурс.sem.acquire();— поток захватывает семафор, уменьшая счетчик. Если счетчик равен нулю, поток блокируется до освобождения семафора.std::cout << "Thread " << thread_id << " is accessing the resource." << std::endl;— критическая секция, где поток работает с ресурсом.sem.release();— поток освобождает семафор, увеличивая счетчик, что позволяет другим потокам захватить его.
Основные различия
- Эксклюзивный доступ: Мьютекс предоставляет эксклюзивный доступ к ресурсу, в то время как семафор может позволять нескольким потокам использовать ресурс одновременно.
- Счетчик: Семафор имеет счетчик, который определяет количество потоков, которые могут одновременно использовать ресурс. Мьютекс такого счетчика не имеет.
- Применение: Мьютекс используется для защиты критических секций, где требуется эксклюзивный доступ, тогда как семафор подходит для управления доступом к ресурсам с ограниченной пропускной способностью.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться