Mutexy, czyli Mutually Exclusive, są to narzędzia programistyczne, które służą do synchronizacji dostępu do współdzielonych zasobów w aplikacjach wielowątkowych. Polegają na tym, że w danym momencie tylko jeden wątek może uzyskać dostęp do danego zasobu, co zapobiega konfliktom i błędom spowodowanym przez współbieżne modyfikacje danych.
Dzięki Mutexom programiści mogą zabezpieczyć dane przed niekontrolowanym dostępem i zapewnić integralność informacji, które są współdzielone pomiędzy wątkami. Mutexy są powszechnie stosowane w aplikacjach, takich jak bazy danych, serwery sieciowe i inne aplikacje wielowątkowe, aby zapewnić bezpieczeństwo i niezawodność działania.

Program obrazujący działanie Mutex-ów został zrealizowany przy użyciu Systemu QNX przez środowisko programistyczne QNX Momentics IDE
Przykład tego, jak może wyglądać wynik działania programu z użyciem mutexów :
Wątek 1: Uzyskanie blokady
Wątek 2: Oczekiwanie na blokadę
Wątek 1: uzyskano blokadę
Wątek 1: Wykonywanie sekcji krytycznej
Wątek 1: Zwalnianie blokady
Wątek 2: uzyskano blokadę
Wątek 2: Wykonywanie sekcji krytycznej
Wątek 2: Zwalnianie blokady
Można zauważyć, że jeden wątek uzyskuje dostęp do zasobu i wykonuje sekcję krytyczną, zanim drugi wątek może uzyskać dostęp do tego samego zasobu. W ten sposób, wątki są uporządkowane i unikają konfliktów podczas dostępu do współdzielonego zasobu.
Poprawny Kod
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int shared_resource = 0;
void *thread_func_1(void *arg)
{
int i;
for (i = 0; i < 100; i++)
{
pthread_mutex_lock(&mutex);
shared_resource++;
printf("Watek 1 zablokowal zasob i zwiekszyl jego wartosc do %d\n", shared_resource);
pthread_mutex_unlock(&mutex);
printf("Watek 1 odblokował zasob \n");
}
return NULL;
}
void *thread_func_2(void *arg)
{
int i;
for (i = 0; i < 100; i++)
{
pthread_mutex_lock(&mutex);
shared_resource++;
printf("Watek 2 zablokowal zasob i zwiekszyl jego wartosc do %d\n", shared_resource);
pthread_mutex_unlock(&mutex);
printf("Watek 2 odblokował zasob \n");
}
return NULL;
}
int main()
{
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, thread_func_1, NULL);
pthread_create(&thread2, NULL, thread_func_2, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("Ostateczna wartosc udostepnionego zasobu: %d\n", shared_resource);
return 0;
}
Wyjście :

W celu ukazania działania Mutex-ów Dodamy błąd funkcje sleep w celu opóźnienia zasobu ;

thread_func_1) nie uwalnia zasobu w odpowiednim czasie (5 sekund), co powoduje, że drugi wątek (thread_func_2) nie może uzyskać dostępu do zasobu. Można zauważyć, że wartość shared_resource jest zwiększana tylko przez jeden wątek na raz. To pokazuje, że mutex chroni przed współbieżnym dostępem do współdzielonego zasobu.Mutexy służą do synchronizacji wątków i zapewnienia, że tylko jeden wątek na raz może korzystać z współdzielonego zasobu. Funkcja sleep użyta w tym przykładzie ma na celu symulować pracę wątku i umożliwić widoczne zobrazowanie działania mutexów. W prawdziwym środowisku, funkcja sleep może być zastąpiona przez inne operacje, takie jak np. przetwarzanie danych, komunikację z innymi wątkami lub procesami, itp. Mutexy są używane w tym celu, aby uniknąć konfliktów podczas dostępu do współdzielonego zasobu i zapewnić, że jego stan jest zawsze konsystentny.
źródła wiedzy : https://pl.wikibooks.org/wiki/POSIX_Threads/Synchronizacja_mi%C4%99dzy_w%C4%85tkami/Mutexy
Tutaj artykuł :