πŸ“Œ Mutex

Mutex (Mutual Exclusion, ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ) β€” ΠΎΠ΄ΠΈΠ½ ΠΈΠ· основных ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠ² синхронизации Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹Ρ… систСмах, ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ доступа ΠΊ раздСляСмым рСсурсам. ΠœΡŒΡŽΡ‚Π΅ΠΊΡ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ Π² ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Π»Π°Π΄Π΅Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΎΠΉ ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с критичСской сСкциСй, прСдотвращая Π³ΠΎΠ½ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅.


🧠 Как Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚

ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏ дСйствия

  • ΠŸΠΎΡ‚ΠΎΠΊ, ΠΆΠ΅Π»Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ раздСляСмому рСсурсу, Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ lock() ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ°.
  • Если ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ свободСн β€” ΠΏΠΎΡ‚ΠΎΠΊ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ ΠΈ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ.
  • Если ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ ΡƒΠΆΠ΅ Π·Π°Ρ…Π²Π°Ρ‡Π΅Π½ Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ β€” Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ блокируСтся (спит), Π½Π΅ потрСбляя CPU, оТидая освобоТдСния.
  • ПослС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с рСсурсом ΠΏΠΎΡ‚ΠΎΠΊ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ unlock(), освобоТдая ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ.
  • Один ΠΈΠ· ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² пробуТдаСтся ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ.

ΠšΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ особСнности

  • Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΈ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ°: Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ОБ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ систСмных Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
  • ΠžΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΠΈΠ΅ busy-wait: Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ спинлока, ΠΏΠΎΡ‚ΠΎΠΊ Π² состоянии оТидания ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ° Π½Π΅ потрСбляСт CPU.
  • ΠŸΠ»Π°Π½ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊ ОБ: ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° постановку ΠΏΠΎΡ‚ΠΎΠΊΠ° Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ оТидания ΠΈ ΠΏΡ€ΠΎΠ±ΡƒΠΆΠ΄Π΅Π½ΠΈΠ΅.
  • Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ рСкурсии: Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ рСкурсивный ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ.
  • Π’Π»Π°Π΄Π΅Π½ΠΈΠ΅: Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΡ‚ΠΎΠΊ, Π·Π°Ρ…Π²Π°Ρ‚ΠΈΠ²ΡˆΠΈΠΉ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ, ΠΌΠΎΠΆΠ΅Ρ‚ Π΅Π³ΠΎ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ.

ПсСвдокод Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠΎΠΌ

function mutex_lock(mutex):
    if mutex is free:
        mutex.owner = current_thread
    else:
        add current_thread to mutex.wait_queue
        block current_thread
 
function mutex_unlock(mutex):
    if mutex.wait_queue not empty:
        wake up one thread from wait_queue
        mutex.owner = that thread
    else:
        mutex.owner = none

βš™οΈ Π“Π΄Π΅ примСняСтся

  • Π’ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹Ρ… ΠΈ многопроцСссорных прилоТСниях.

  • Π’ ядрах ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… систСм для Π·Π°Ρ‰ΠΈΡ‚Ρ‹ критичСских сСкций.

  • Π’ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ… ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΠΈΠ·ΠΌΠ° ΠΈ многопоточности.

  • Π’ систСмах Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ с ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠ»Π΅Π½ΠΈΠ΅ΠΌ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΎΠ².

  • Π’ ΠΊΠ»ΠΈΠ΅Π½Ρ‚-сСрвСрных прилоТСниях, Π±Π°Π·Π°Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, сСтСвых сСрвисах.


βœ… ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²Π°

  • МинимальноС ΠΏΠΎΡ‚Ρ€Π΅Π±Π»Π΅Π½ΠΈΠ΅ CPU ΠΏΡ€ΠΈ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ.

  • Гарантия Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈ цСлостности Π΄Π°Π½Π½Ρ‹Ρ….

  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΎΠ² ΠΈ справСдливости (Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… рСализациях).

  • РСкурсивныС вСрсии для упрощСния слоТной Π»ΠΎΠ³ΠΈΠΊΠΈ.

  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚ΠΎΠ² оТидания ΠΈ прСрываСмости.


❌ НСдостатки

  • ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ контСкста ΠΏΡ€ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ΅/Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ΅ β€” Π½Π°ΠΊΠ»Π°Π΄Π½Ρ‹Π΅ расходы.

  • Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π΄Π΅Π΄Π»ΠΎΠΊΠΎΠ² ΠΏΡ€ΠΈ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΌ использовании.

  • ΠŸΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½ΠΎΠ΅ инвСрсированиС β€” Π½ΠΈΠ·ΠΊΠΎΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ высокоприоритСтный.

  • Π‘ΠΎΠ»Π΅Π΅ мСдлСнная рСакция ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ со спинлоками ΠΏΡ€ΠΈ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΡ… критичСских сСкциях.

  • Π‘Π»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈ ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ.


πŸ”— БвязанныС Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ

Spinlock, Semaphore, Futex, Atomic Operation, Condition Variable, Thread, Scheduler, Deadlock, Priority Inversion, Lock-Free, RTOS, POSIX Threads


РСзюмС

Mutex β€” ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ синхронизации для Π·Π°Ρ‰ΠΈΡ‚Ρ‹ критичСских сСкций, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ бСзопасно Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с раздСляСмыми рСсурсами Π±Π΅Π· Π³ΠΎΠ½ΠΎΠΊ ΠΈ поврСТдСния Π΄Π°Π½Π½Ρ‹Ρ…. Он Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠΎΡ‚ΠΎΠΊ Π² случаС занятости рСсурса, освобоТдая CPU для Π΄Ρ€ΡƒΠ³ΠΈΡ… Π·Π°Π΄Π°Ρ‡. Однако Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ остороТности ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ Π΄Π΅Π΄Π»ΠΎΠΊΠΎΠ² ΠΈ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½ΠΎΠΉ инвСрсии.


🧩 Π‘Π»ΠΎΠΊ-схСма Ρ€Π°Π±ΠΎΡ‚Ρ‹ Mutex

flowchart TB
    Thread1["Thread 1"]
    Thread2["Thread 2"]
    Mutex["Mutex Lock"]
    Resource["Shared Resource"]

    Thread1 -->|lock| Mutex
    Mutex -->|grant access| Thread1
    Thread1 -->|use| Resource
    Thread1 -->|unlock| Mutex

    Thread2 -->|lock| Mutex
    Mutex -->|block Thread 2| Thread2
    Mutex -->|grant access| Thread2
    Thread2 -->|use| Resource
    Thread2 -->|unlock| Mutex

    style Mutex stroke:#fff,stroke-width:5px,font-weight:bold

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΊΠΎΠ΄Π°

C: простой mutex с использованиСм POSIX Threads (pthread)

#include <pthread.h>
#include <stdio.h>
 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
void* thread_func(void* arg) {
    pthread_mutex_lock(&mutex);
    printf("Thread %ld acquired the mutex\n", (long)arg);
    // критичСская сСкция
    pthread_mutex_unlock(&mutex);
    return NULL;
}
 
int main() {
    pthread_t t1, t2;
    pthread_create(&t1, NULL, thread_func, (void*)1);
    pthread_create(&t2, NULL, thread_func, (void*)2);
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    return 0;
}

C++: std::mutex

#include <mutex>
#include <thread>
#include <iostream>
 
std::mutex mtx;
 
void thread_func(int id) {
    mtx.lock();
    std::cout << "Thread " << id << " entered critical section\n";
    mtx.unlock();
}
 
int main() {
    std::thread t1(thread_func, 1);
    std::thread t2(thread_func, 2);
    t1.join();
    t2.join();
    return 0;
}

Linux Kernel: использованиС mutex

struct mutex my_mutex;
 
mutex_init(&my_mutex);
 
void critical_section(void) {
    mutex_lock(&my_mutex);
    // критичСская сСкция
    mutex_unlock(&my_mutex);
}

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊΠΈ:
POSIX Threads documentation, C++ Standard Library, Linux Kernel Synchronization docs, β€œOperating Systems: Three Easy Pieces”, Wikipedia, osdev.org.