Чи є різниця між бінарним семафором і мютекс або вони по суті однакові?
Чи є різниця між бінарним семафором і мютекс або вони по суті однакові?
Відповіді:
Вони НЕ одне і те ж. Вони використовуються для різних цілей!
Хоча обидва типи семафорів мають повний / порожній стан і використовують один і той же API, їх використання дуже відрізняється.
Семафори взаємного виключення Семафори
взаємного виключення використовуються для захисту спільних ресурсів (структура даних, файл тощо).
Семафор Mutex "належить" завданню, яке його бере. Якщо Завдання B намагається передати semtex в мютекс, який зараз знаходиться у завданні A, виклик завдання B поверне помилку та не вдасться.
Mutexes завжди використовує таку послідовність:
- SemTake - Критичний розділ - SemGive
Ось простий приклад:
Нитка A Нитка B Візьміть Мутекс доступ до даних ... Візьміть Mutex <== Заблокуємо ... Надати Mutex дані доступу <== Розблокувати ... Дайте Мутекс
Бінарний семафор
Бінарний семафор стосується зовсім іншого питання:
Task A Task B
... Take BinSemaphore <== wait for something
Do Something Noteworthy
Give BinSemaphore do something <== unblocks
Зауважте, що з двійковим семафором нормально B взяти семафор, а A - надати його.
Знову ж таки, двійковий семафор НЕ захищає ресурс від доступу. Акт дарування та взяття семафору принципово відокремлений.
Зазвичай це мало сенсу для одного і того ж завдання, щоб дати подачу і взяти на себе той же бінарний семафор.
тому семафори більше підходять для деяких проблем синхронізації, таких як виробник-споживач.
У Windows бінарні семафори більше схожі на предмети події, ніж на мутекси.
Mutex can be released only by thread that had acquired it
- Я щойно спробував за допомогою простої програми на основі pthread_mutex, потік може розблокувати mutex, заблокований у головній темі
Приклад туалету - це приємна аналогія:
Mutex:
Є ключем до туалету. Один чоловік може мати ключ - займати туалет - в той час. Закінчивши, людина дає (звільняє) ключ наступній людині в черзі.
Офіційно: "Mutexes зазвичай використовуються для послідовного доступу до розділу коду повторного вступу, який не може бути виконаний одночасно більш ніж одним потоком. Об'єкт mutex дозволяє лише один потік в керований розділ, змушуючи інші потоки, які намагаються отримати доступ до цей розділ чекати, поки перший потік не вийде з цього розділу. " Ref: Бібліотека розробників Symbian
(Мютекс - це справді семафор зі значенням 1.)
Семафор:
Чи кількість безкоштовних однакових ключів для туалету. Наприклад, скажімо, у нас є чотири туалети з однаковими замками та ключами. Кількість семафорів - кількість ключів - встановлюється на початку 4 (усі чотири туалети безкоштовні), тоді значення підрахунку зменшується по мірі заходу людей. Якщо всі туалети заповнені, тобто. не залишилося вільних клавіш, кількість семафорів дорівнює 0. Тепер, коли екв. одна людина виходить з туалету, семафор збільшується до 1 (один вільний ключ) і видається наступній людині в черзі.
Офіційно: "Семафор обмежує кількість одночасних користувачів спільного ресурсу до максимальної кількості. Нитки можуть запитувати доступ до ресурсу (декрементація семафору) і можуть сигналізувати про те, що вони закінчили використовувати ресурс (збільшуючи семафор). " Ref: Бібліотека розробників Symbian
Приємні статті на тему:
З частини 2:
Мутекс схожий з принципами бінарного семафору з однією суттєвою відмінністю: принципом власності. Власність - це проста концепція, що коли завдання блокує (набуває) мютекс, він може розблокувати (звільнити) його. Якщо завдання намагається розблокувати мютекс, який він не заблокував (таким чином, він не є власником), виникає умова помилки, а головне, мютекс не розблокований. Якщо об'єкт взаємного виключення не має права власності, то, незважаючи на те, що він називається, це не мутекс.
Оскільки жоден з вищезазначених відповідей не усуває плутанину, ось такий, який очистив мою плутанину.
Строго кажучи, мютекс - це механізм блокування, який використовується для синхронізації доступу до ресурсу. Лише одне завдання (це може бути потік або процес, заснований на абстракції ОС), може набувати мутекс. Це означає, що право власності на mutex буде пов’язане, і лише власник може звільнити замок (mutex).
Семафор - це механізм сигналізації (вид "Я закінчую, ти можеш продовжувати"). Наприклад, якщо ви слухаєте пісні (припускайте це як одне завдання) на своєму мобільному телефоні і в той же час ваш друг зателефонував вам, буде спровоковано переривання, під час якого функція обслуговування переривання (ISR) буде сигналізувати про задачу обробки дзвінків для пробудження .
Їх семантика синхронізації сильно відрізняється:
Як такий, ми можемо бачити мутекс як маркер, що передається від завдання до завдань, і семафор як червоне світло руху (це сигналізує комусь, що він може продовжуватись).
На теоретичному рівні вони семантично не відрізняються. Ви можете реалізувати mutex за допомогою семафорів або навпаки (див. Тут приклад). На практиці реалізація різна, і вони пропонують дещо різні послуги.
Практична відмінність (з точки зору системних служб, що їх оточують) полягає в тому, що реалізація мютексу спрямована на створення більш легкого механізму синхронізації. У мові, що говорить оракул, мютекси відомі як засувки, а семафори відомі як чекання .
На найнижчому рівні вони використовують якийсь механізм атомного випробування та встановлення . Це зчитує поточне значення місця в пам'яті, обчислює якесь умовне і записує значення в цьому місці в одній інструкції, яку неможливо перервати . Це означає, що ви можете придбати мютекс і перевірити, чи не було у вас когось іншого перед вами.
Типова реалізація mutex має процес або потік, що виконує інструкцію тестування та встановлення та оцінює, чи не встановило щось інше mutex. Ключовим моментом тут є те, що немає взаємодії з планувальником , тому ми не маємо уявлення (і все одно), хто встановив блокування. Тоді ми або відмовляємося від свого часового відрізка і намагаємося його повторно, коли завдання буде переплановано, або виконаємо спін-блокування . Спіновий замок - це такий алгоритм, як:
Count down from 5000:
i. Execute the test-and-set instruction
ii. If the mutex is clear, we have acquired it in the previous instruction
so we can exit the loop
iii. When we get to zero, give up our time slice.
Коли ми закінчимо виконання нашого захищеного коду (відомий як критичний розділ ), ми просто встановимо значення mutex у нуль або будь-що означає «очистити». Якщо декілька завдань намагаються придбати мютекс, то наступне завдання, яке трапляється заплановано після випуску файлу, отримає доступ до ресурсу. Зазвичай ви використовуєте мутекси для керування синхронізованим ресурсом, коли ексклюзивний доступ потрібен лише на дуже короткий проміжок часу, як правило, для оновлення спільної структури даних.
Семафор - це синхронізована структура даних (як правило, використовуючи мютекс), що має кількість та обгортки системних викликів, які взаємодіють із планувальником на трохи більшій глибині, ніж би бібліотеки mutex. Семафори збільшуються та зменшуються та використовуються для блокування завдань, поки щось інше не буде готове. Див. Проблема виробника / споживача для простого прикладу цього. Семафори ініціалізуються на деяке значення - бінарний семафор - це лише особливий випадок, коли семафор ініціалізується до 1. Опублікування семафору призводить до пробудження процесу очікування.
Основний алгоритм семафору виглядає так:
(somewhere in the program startup)
Initialise the semaphore to its start-up value.
Acquiring a semaphore
i. (synchronised) Attempt to decrement the semaphore value
ii. If the value would be less than zero, put the task on the tail of the list of tasks waiting on the semaphore and give up the time slice.
Posting a semaphore
i. (synchronised) Increment the semaphore value
ii. If the value is greater or equal to the amount requested in the post at the front of the queue, take that task off the queue and make it runnable.
iii. Repeat (ii) for all tasks until the posted value is exhausted or there are no more tasks waiting.
У випадку двійкового семафору основною практичною відмінністю між ними є характер системних служб, що оточують фактичну структуру даних.
РЕДАКТУВАННЯ: Як справедливо зазначав Еван, спіллокс сповільнить роботу однієї процесорної машини. Ви б використовували спінлок на мультипроцесорній коробці, оскільки на одному процесорі процес, що містить мутекс, ніколи не скине його під час виконання іншого завдання. Спінлок корисний лише для багатопроцесорних архітектур.
futex
системний виклик Linux існує для сприяння реалізації файлів mutex / semaphore з низькою затримкою. en.wikipedia.org/wiki/Futex ) На швидкому шляху без суперечок або якщо ресурс стане доступним незабаром, ви ніколи не матимете накладних витрат системний виклик. Але ви не витрачаєте більше декількох мікросекунд, зайнятих в очікуванні (прядіння). Налаштування параметрів відключення та очікування залежить, звичайно, від апаратного та навантаження, але стандартна бібліотека, як правило, має розумний вибір.
Хоча mutex і семафори використовуються як примітиви синхронізації, між ними існує велика різниця. Що стосується мутексу, розблокувати його може лише нитка, яка заблокувала або придбала мютекс. У випадку семафору нитка, що чекає на семафорі, може сигналізуватися іншою ниткою. Деякі операційні системи підтримують використання мутексу та семафорів між процесом. Зазвичай використання створюється у спільній пам'яті.
Mutex: Припустимо, у нас є критична нитка розділу T1, яка хоче отримати доступ до неї, після чого слід нижче. T1:
Бінарний семафор: Він працює на основі сигналу очікування та сигналу. очікування (і) зменшення значення "s" на одне зазвичай значення "s" ініціалізується зі значенням "1", сигнал (и) збільшує значення "s" на одиницю. якщо значення "s" дорівнює 1 означає, що ніхто не використовує критичний розділ, коли значення 0 означає, що критичний розділ використовується. припустимо, що нитка Т2 використовує критичний переріз, тоді це слід нижче. T2:
Основна відмінність між Mutex і Бінарним семафором полягає в Mutext, якщо нитка блокує критичну секцію, тоді вона має розблокувати критичну секцію, жодна інша нитка не може її розблокувати, але у випадку бінарного семафору, якщо одна нитка блокує критичну секцію за допомогою функції очікування (s), тоді значення з s стають "0", і ніхто не може отримати доступ до нього, поки значення "s" не стане 1, але припустимо, що деякий інший сигнал виклику потоку тоді значення "s" стає 1, і це дозволяє іншій функції використовувати критичну секцію. отже, у бінарному семафорному потоці немає права власності.
У Windows є дві відмінності між мютексами та бінарними семафорами:
Мутекс може бути випущений лише тим потоком, який має право власності, тобто потоком, який раніше називався функцією Wait (або який взяв право власності при його створенні). Семафор може бути звільнений будь-якою ниткою.
Нитка може повторно викликати функцію очікування на mutex, не блокуючи її. Однак якщо двічі викликати функцію очікування на двійковому семафорі, не звільняючи семафор між ними, потік блокується.
Ви, очевидно, використовуєте mutex для блокування даних в одному потоці, отримуючи доступ до іншого потоку одночасно. Припустимо, що ви щойно зателефонували lock()
та отримуєте доступ до даних. Це означає, що ви не очікуєте, що будь-який інший потік (або інший екземпляр того ж коду потоку) отримає доступ до тих самих даних, заблокованих тим самим мутекс. Тобто, якщо це той самий потік-код, який виконується на іншому екземплярі потоку, потрапляє в замок, тоlock()
має перекрити там контрольний потік. Це стосується потоку, який використовує інший потіковий код, який також отримує доступ до тих самих даних і який також блокується тим самим мютекс. У цьому випадку ви все ще перебуваєте в процесі доступу до даних, і ви можете зайняти, скажімо, ще 15 секунд, щоб дістатися до розблокування файлу mutex (щоб другий потік, який заблокується в блокуванні mutex, розблокував і дозволив керувати доступ до даних). Чи дозволите ви будь-якою ціною дозволити ще одному потоку просто розблокувати той самий мютекс, а ви, в свою чергу, дозволити потоці, яка вже чекає (блокується) в блоці mutex, розблокувати та отримати доступ до даних? Сподіваюся, ви отримали те, що я тут говорю? Відповідно до загального визначення !,
Отже, якщо ви дуже конкретно ставитесь до використання бінарного семафору замість мютексу, то вам слід бути дуже обережним у “обстеженні” замків та розблокувань. Я маю на увазі, що кожен потік управління, який потрапляє на кожен замок, повинен потрапляти на виклик розблокування, також не повинно бути "першого розблокування", скоріше він повинен бути "першим блокуванням".
Mutex використовуються для "Замикаючих механізмів". один процес за один раз може використовувати спільний ресурс
тоді як
Семафори використовуються для "Механізмів сигналізації" на кшталт "Я закінчив, тепер можна продовжувати"
Міф:
Пара статей говорить про те, що "бінарний семафор і мютекс однакові" або "Семафор зі значенням 1 є мутекс", але основна відмінність полягає в тому, що Mutex може бути випущений лише потоком, який його придбав, тоді як ви можете сигналізувати семафору з будь-якого іншого потоку
Ключові моменти:
• Нитка може придбати більше одного замка (Mutex).
• Мютекс може бути заблокований не раз, лише якщо його рекурсивна мютекс, тут і блокування, і розблокування для мютексу повинні бути однаковими
• Якщо потік, який уже заблокував мютекс, спробує знову заблокувати мютекс, він увійде до списку очікування цього файлу, що призводить до тупикової ситуації.
• Бінарний семафор і мютекс схожі, але не однакові.
• Mutex - це затратна експлуатація завдяки пов'язаним з нею протоколам захисту.
• Основна мета mutex - досягнення атомного доступу або блокування ресурсу
Мьютекса контролює доступ до одного спільного ресурсу. Він надає операції з отримання () доступу до цього ресурсу та випуску (), коли це зроблено.
Семафор управляє доступом до загального пулу ресурсів. Він надає операції Wait (), поки не стане доступним один із ресурсів у пулі, і Signal (), коли він повернеться до пулу.
Коли кількість ресурсів, які захищає Семафор, перевищує 1, це називається лічильним семафором . Коли він керує одним ресурсом, його називають булевим семафором . Булевий семафор еквівалентний мутексу.
Таким чином, Семафор є абстракцією більш високого рівня, ніж Мутекс. Mutex можна реалізувати за допомогою Semaphore, але не навпаки.
Модифіковане запитання - в чому різниця між мютекс та "бінарним" семафором у "Linux"?
Відповідь: Нижче наведені відмінності - i) Сфера застосування - Область застосування мютексу знаходиться в просторі адресного процесу, який створив її, і використовується для синхронізації потоків. Тоді як семафор може використовуватися в просторі процесу, а значить, він може використовуватися для міжпроцесорної синхронізації.
ii) Мутекс легший і швидший, ніж семафор. Футекс ще швидше.
iii) Mutex може бути придбаний одним і тим же потоком успішно кілька разів, за умови, що він повинен випустити його стільки ж разів. Інша нитка, яка намагається придбати, заблокується. Якщо у випадку семафору, якщо той самий процес намагається знову придбати його, він блокується, оскільки його можна придбати лише один раз.
Різниця між Бінарним Семафором та Мутексом: ВЛАСНІСТЬ: Семафори можуть сигналізуватися (розміщуватися) навіть від поточного власника. Це означає, що ви можете просто розмістити повідомлення з будь-якої іншої теми, хоча ви не є власником.
Семафор - це публічна власність, яка перебуває в процесі роботи, вона може бути просто розміщена потоком, що не є власником. Будь ласка, позначте цю різницю сміливими літерами, це багато значить.
Mutex працює над блокуванням критичної області, але Semaphore працює на рахунку.
http://www.geeksforgeeks.org/archives/9102 детально обговорює.
Mutex
це механізм блокування, який використовується для синхронізації доступу до ресурсу.
Semaphore
є механізмом сигналізації.
Це залежить від програміста, якщо він хоче використовувати двійковий семафор замість мутексу.
Крім того, що у мютексів є власник, два об'єкти можуть бути оптимізовані для різного використання. Мутекси призначені для утримання лише короткий час; порушення цього може призвести до низької продуктивності та несправедливого планування. Наприклад, запущеній нитці може бути дозволено придбати мютекс, навіть якщо інша нитка вже заблокована на ній. Семафори можуть забезпечити більшу справедливість, або справедливість може бути змушена використовувати декілька змінних умов.
sem_post()
для SCHED_FIFO
і SCHED_RR
(обидва з них не по замовчуванням): найвищий пріоритет потоку, і , якщо є кілька з тим же пріоритетом, нитки , які довго чекали довше. OpenSolaris певною мірою дотримується цього правила FIFO навіть для звичайного планування. Для glibc та FreeBSD розблокування простого мютексу (тобто не пріоритетного захисту чи пріоритетного успадкування) та розміщення семафору в основному однакові, позначаючи об'єкт як розблокований, а потім, якщо можуть бути потоки очікування, закликаючи ядро прокинути його.
У вікнах різниця вказана нижче. MUTEX: процес, який успішно виконує очікування , повинен виконати сигнал і навпаки. БІНАРНІ СЕМАФОРИ: Різні процеси можуть виконувати операцію очікування або сигналу на семафорі.
Хоча двійковий семафор може використовуватися як мутекс, мутекс є більш конкретним випадком використання, оскільки тільки процес, який заблокував мутекс, повинен розблокувати його. Це обмеження власності дозволяє забезпечити захист від:
Ці обмеження не завжди є, оскільки вони погіршують швидкість. Під час розробки коду ви можете включити ці перевірки тимчасово.
наприклад, ви можете увімкнути атрибут перевірки помилок у вашому файлі mutex. Помилка перевірки файлів mutexes повертається, EDEADLK
якщо ви спробуєте заблокувати той самий двічі та EPERM
якщо ви розблокуєте мутекс, який не є вашим.
pthread_mutex_t mutex;
pthread_mutexattr_t attr;
pthread_mutexattr_init (&attr);
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
pthread_mutex_init (&mutex, &attr);
Після ініціалізації ми можемо помістити ці чеки в наш код так:
if(pthread_mutex_unlock(&mutex)==EPERM)
printf("Unlock failed:Mutex not owned by this thread\n");
Концепція була зрозумілою мені після переходу вище посад. Але були деякі затяжні питання. Отже, я написав цей невеликий фрагмент коду.
Коли ми намагаємось дати семафор, не приймаючи його, він проходить. Але, коли ви намагаєтесь надати мютекс, не беручи його, він не вдається. Я тестував це на платформі Windows. Увімкніть USE_MUTEX для запуску одного і того ж коду за допомогою MUTEX.
#include <stdio.h>
#include <windows.h>
#define xUSE_MUTEX 1
#define MAX_SEM_COUNT 1
DWORD WINAPI Thread_no_1( LPVOID lpParam );
DWORD WINAPI Thread_no_2( LPVOID lpParam );
HANDLE Handle_Of_Thread_1 = 0;
HANDLE Handle_Of_Thread_2 = 0;
int Data_Of_Thread_1 = 1;
int Data_Of_Thread_2 = 2;
HANDLE ghMutex = NULL;
HANDLE ghSemaphore = NULL;
int main(void)
{
#ifdef USE_MUTEX
ghMutex = CreateMutex( NULL, FALSE, NULL);
if (ghMutex == NULL)
{
printf("CreateMutex error: %d\n", GetLastError());
return 1;
}
#else
// Create a semaphore with initial and max counts of MAX_SEM_COUNT
ghSemaphore = CreateSemaphore(NULL,MAX_SEM_COUNT,MAX_SEM_COUNT,NULL);
if (ghSemaphore == NULL)
{
printf("CreateSemaphore error: %d\n", GetLastError());
return 1;
}
#endif
// Create thread 1.
Handle_Of_Thread_1 = CreateThread( NULL, 0,Thread_no_1, &Data_Of_Thread_1, 0, NULL);
if ( Handle_Of_Thread_1 == NULL)
{
printf("Create first thread problem \n");
return 1;
}
/* sleep for 5 seconds **/
Sleep(5 * 1000);
/*Create thread 2 */
Handle_Of_Thread_2 = CreateThread( NULL, 0,Thread_no_2, &Data_Of_Thread_2, 0, NULL);
if ( Handle_Of_Thread_2 == NULL)
{
printf("Create second thread problem \n");
return 1;
}
// Sleep for 20 seconds
Sleep(20 * 1000);
printf("Out of the program \n");
return 0;
}
int my_critical_section_code(HANDLE thread_handle)
{
#ifdef USE_MUTEX
if(thread_handle == Handle_Of_Thread_1)
{
/* get the lock */
WaitForSingleObject(ghMutex, INFINITE);
printf("Thread 1 holding the mutex \n");
}
#else
/* get the semaphore */
if(thread_handle == Handle_Of_Thread_1)
{
WaitForSingleObject(ghSemaphore, INFINITE);
printf("Thread 1 holding semaphore \n");
}
#endif
if(thread_handle == Handle_Of_Thread_1)
{
/* sleep for 10 seconds */
Sleep(10 * 1000);
#ifdef USE_MUTEX
printf("Thread 1 about to release mutex \n");
#else
printf("Thread 1 about to release semaphore \n");
#endif
}
else
{
/* sleep for 3 secconds */
Sleep(3 * 1000);
}
#ifdef USE_MUTEX
/* release the lock*/
if(!ReleaseMutex(ghMutex))
{
printf("Release Mutex error in thread %d: error # %d\n", (thread_handle == Handle_Of_Thread_1 ? 1:2),GetLastError());
}
#else
if (!ReleaseSemaphore(ghSemaphore,1,NULL) )
{
printf("ReleaseSemaphore error in thread %d: error # %d\n",(thread_handle == Handle_Of_Thread_1 ? 1:2), GetLastError());
}
#endif
return 0;
}
DWORD WINAPI Thread_no_1( LPVOID lpParam )
{
my_critical_section_code(Handle_Of_Thread_1);
return 0;
}
DWORD WINAPI Thread_no_2( LPVOID lpParam )
{
my_critical_section_code(Handle_Of_Thread_2);
return 0;
}
Сам факт, що семафор дозволяє вам сигналізувати "це робиться за допомогою ресурсу", навіть якщо він ніколи не володів цим ресурсом, змушує мене думати, що між володінням та сигналізацією у випадку семафорів існує дуже нещільна зв'язок.
Mutex використовується для захисту чутливого коду та даних, семафор використовується для синхронізації. Ви також можете практично використовувати захист чутливого коду, але може виникнути ризик звільнення захисту іншим потоком операцією V.So Основна Різниця між бісемафором і мютекс - це право власності. Наприклад, туалет, Mutex такий, що можна входити до туалету і зачиняти двері, ніхто більше не може входити, поки чоловік не вийде, бісемафор - це такий, як можна ввійти. туалет і замкнути двері, але хтось інший міг би увійти, попросивши адміністратора відкрити двері, це смішно.
Мутекс
Mutexes зазвичай використовуються для послідовного доступу до розділу коду повторного вступу, який не може бути виконаний одночасно більш ніж одним потоком. Об'єкт mutex дозволяє лише один потік в контрольованому розділі, змушуючи інші потоки, які намагаються отримати доступ до цього розділу, чекати, поки перший потік не вийде з цього розділу. Попереднє використання mutex для захисту спільного ресурсу може становити небезпеку ненавмисний побічний ефект. Будь-які два завдання RTOS, які працюють з різними пріоритетами та координуються через мьютекс, створюють можливість для інверсії пріоритетів . Mutex працює в просторі користувача .
Семафор
Семафор - це механізм сигналізації. Семафор обмежує кількість одночасних користувачів спільного ресурсу до максимальної кількості. Нитки можуть запитувати доступ до ресурсу (декрементування семафору) і можуть сигналізувати про те, що вони закінчили використовувати ресурс (збільшуючи семафор). Це дозволяє кількості потоків отримати доступ до спільних ресурсів. Правильне використання семафору призначене для передачі сигналу від однієї задачі до іншої. Семафори також можуть бути використані для передачі сигналу від звичайної служби переривання (ISR) до завдання. Сигналізація семафору - це не блокуюча поведінка RTOS і, таким чином, безпечна для ISR. Оскільки ця методика виключає схильність до помилок, потрібно відключити переривання на рівні завдання. Це працює в просторі ядра .
Відповідь може залежати від цільової ОС. Наприклад, щонайменше одна реалізація RTOS, з якою я знайома, дозволить кілька послідовних операцій «дістати» проти одного мутексу ОС, доки вони всі з одного контексту потоку. Багаторазове отримання має бути замінено рівним числом ставок, перш ніж інша нитка буде дозволена для отримання мютексу. Це відрізняється від бінарних семафорів, для яких дозволено одночасне отримання одночасно, незалежно від контексту потоку.
Ідея цього типу mutex полягає в тому, що ви захищаєте об'єкт, дозволяючи лише одному контексту змінювати дані за один раз. Навіть якщо потік отримує mutex і потім викликає функцію, яка додатково модифікує об'єкт (і отримує / ставить мутекс протектора навколо його власних операцій), операції все одно повинні бути безпечними, оскільки всі вони відбуваються під однією ниткою.
{
mutexGet(); // Other threads can no longer get the mutex.
// Make changes to the protected object.
// ...
objectModify(); // Also gets/puts the mutex. Only allowed from this thread context.
// Make more changes to the protected object.
// ...
mutexPut(); // Finally allows other threads to get the mutex.
}
Звичайно, користуючись цією функцією, ви повинні бути впевнені, що всі звернення в межах однієї нитки справді є безпечними!
Я не впевнений, наскільки поширений такий підхід чи застосовується він поза системами, з якими я знайомий. Для прикладу такого роду mutex див. RTOS ThreadX.
Мутекси мають право власності, на відміну від семафорів. Хоча будь-який потік, що знаходиться в межах mutex, може отримати розблокований мютекс і заблокувати доступ до одного і того ж критичного розділу коду, тільки нитка, що заблокувала мютекс, повинна розблокувати його .
Як уже згадували багато людей, мютекс використовується для захисту критичного фрагмента коду (критичний розділ AKA.) Ви придбаєте мютекс (замок), введете критичний розділ і випустите файл mutex (розблокуйте) у тому ж потоці .
Використовуючи семафор, ви можете змусити нитку зачекати на семафорі (скажімо, потік А), поки інша нитка (скажімо, нитка В) не виконає будь-яке завдання, а потім встановить Семафор для потоку А, щоб зупинити очікування, і продовжити своє завдання.
Найкраще рішення
Єдина відмінність
1.Mutex -> блокування та розблокування перебувають у власності на потоці, що блокує мютекс.
2.Semaphore -> Немає права власності, тобто; якщо одна нитка викликає semwait (s), будь-який інший потік може викликати sempost (s), щоб зняти замок.
MUTEX
Донедавна єдиним сплячим замком у ядрі був семафор. Більшість користувачів семафорів створили семафор з кількістю одиниць і трактували їх як замок взаємного виключення - сплячу версію спін-блокування. На жаль, семафори є досить загальними і не обмежують використання. Це робить їх корисними для керування ексклюзивним доступом у неясних ситуаціях, таких як складні танці між ядром та простором користувачів. Але це також означає, що простіше блокувати важче, а відсутність примусових правил унеможливлює будь-який тип автоматизованої налагодження чи виконання обмежень. Шукаючи більш простий замок для сну, розробники ядра представили mutex. Так, як ви звикли, це заплутане ім'я. Давайте уточнимо. Термін "мютекс" - це загальна назва для позначення будь-якого сплячого замка, який вимагає взаємного виключення, наприклад, семафор з кількістю використання. В останніх ядрах Linux власне іменник "mutex" тепер також є специфічним типом сплячого блоку, який реалізує взаємне виключення.
Простота та ефективність мютексу випливають із додаткових обмежень, які він накладає на своїх користувачів понад і вище, ніж вимагає семафор. На відміну від семафору, який реалізує найосновніше поведінку згідно з оригінальним дизайном Дійкстри, мютекс має більш жорсткий і вузький випадок використання: n Лише одне завдання може утримувати мутекс одночасно. Тобто, кількість використання мютексу завжди одна.
[1] Розробка ядра Linux, Третє видання Роберт Лав
Я думаю, що більшість відповідей тут бентежать, особливо ті, що говорять про те, що мютекс може бути випущений лише процесом, який його затримує, але семафор може бути сигналізований за допомогою цього процесу. Наведений рядок є своєрідним розпливчастим щодо семафору. Для розуміння нам слід знати, що існує два види семафору, один називається рахунковим семафором, а другий називається бінарним семафором. При підрахунку семафору обробляється доступ до n кількості ресурсів, де n можна визначити перед використанням. Кожен семафор має змінну лічильника, яка зберігає підрахунок кількості використовуваних ресурсів, спочатку він встановлюється на n. Кожен процес, який бажає використовувати ресурс, виконує операцію очікування () на семафорі (тим самим зменшуючи кількість). Коли процес звільняє ресурс, він виконує операцію release () (збільшуючи кількість). Коли кількість стає 0, всі ресурси використовуються. Після цього процес чекає, поки кількість не стане більше 0. Тепер ось лише вилов лише той процес, який містить ресурс, може збільшити кількість жоден інший процес не може збільшити кількість, тільки процеси, що містять ресурс, можуть збільшити кількість і процес чекаючи, коли семафор знову перевірить, і коли він побачить доступний ресурс, він знову зменшує кількість. Таким чином, з точки зору бінарного семафору, тільки процес, що тримає семафор, може збільшити кількість, а кількість залишається нульовою, доки вона не припинить використовувати семафор і не збільшить кількість, а інший процес отримає шанс отримати доступ до семафору. Тепер ось лише вилов лише той процес, який містить ресурс, може збільшити кількість жоден інший процес не може збільшити кількість, тільки процеси, що містять ресурс, можуть збільшити кількість, і процес, який чекає на семафор, знову перевіряє, і коли він бачить ресурс, доступний йому зменшує кількість знову. Таким чином, з точки зору бінарного семафору, тільки процес, що тримає семафор, може збільшити кількість, а кількість залишається нульовою, доки вона не припинить використовувати семафор і не збільшить кількість, а інший процес отримає шанс отримати доступ до семафору. Тепер ось лише вилов лише той процес, який містить ресурс, може збільшити кількість жоден інший процес не може збільшити кількість, тільки процеси, що містять ресурс, можуть збільшити кількість, і процес, який чекає на семафор, знову перевіряє, і коли він бачить ресурс, доступний йому зменшує кількість знову. Таким чином, з точки зору бінарного семафору, тільки процес, що тримає семафор, може збільшити кількість, а кількість залишається нульовою, доки вона не припинить використовувати семафор і не збільшить кількість, а інший процес отримає шанс отримати доступ до семафору.
Основна відмінність бінарного семафору від мютексу полягає в тому, що семафор є сигнальним механізмом, а мютекс - блокувальним механізмом, але бінарний семафор, здається, функціонує як мутекс, який створює плутанину, але обидва - це різні концепції, придатні для різних видів роботи.