π 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.