← Назад ко всем вопросам

В чем разница между семафором и мьютексом

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(); — поток освобождает семафор, увеличивая счетчик, что позволяет другим потокам захватить его.

Основные различия

  1. Эксклюзивный доступ: Мьютекс предоставляет эксклюзивный доступ к ресурсу, в то время как семафор может позволять нескольким потокам использовать ресурс одновременно.
  2. Счетчик: Семафор имеет счетчик, который определяет количество потоков, которые могут одновременно использовать ресурс. Мьютекс такого счетчика не имеет.
  3. Применение: Мьютекс используется для защиты критических секций, где требуется эксклюзивный доступ, тогда как семафор подходит для управления доступом к ресурсам с ограниченной пропускной способностью.

Тема: Многопоточность / Синхронизация
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки