Bariera – jeden z najpowszechniejszych rodzajów synchronizacji wątków (procesów) w przetwarzaniu równoległym.

Istnieją gotowe biblioteki implementujące bariery np. pthread.h w standarzie POSIX. Barierę można także zaimplementować ręczenie za pomocą muteksów.

Przykład Przykład kodu w języku C, używający pthread.h do synchronizacji wątków za pomocą bariery,

#include <stdio.h> #include <pthread.h> #include <unistd.h>

#define LICZBA_WATKOW 3

// Deklaracja bariery pthread_barrier_t bariera;

void* zadanie(void* id) { long numer = (long)id;

printf("Wątek %ld: Rozpoczynam etap 1...\n", numer); sleep(numer); // Symulacja pracy o różnym czasie trwania

printf("Wątek %ld: Dotarłem do bariery i czekam.\n", numer);

// Punkt synchronizacji - wątek zatrzymuje się tutaj, // dopóki wszystkie wątki nie wywołają tej funkcji. pthread_barrier_wait(&bariera);

printf("Wątek %ld: Przekroczyłem barierę, zaczynam etap 2.\n", numer);

return NULL; }

int main() { pthread_t watki[LICZBA_WATKOW];

// Inicjalizacja bariery dla określonej liczby wątków pthread_barrier_init(&bariera, NULL, LICZBA_WATKOW);

// Tworzenie wątków for (long i = 0; i < LICZBA_WATKOW; i++) { pthread_create(&watki[i], NULL, zadanie, (void*)i);

// Oczekiwanie na zakończenie wątków for (int i = 0; i < LICZBA_WATKOW; i++) { pthread_join(watki[i], NULL);

// Zwolnienie zasobów bariery pthread_barrier_destroy(&bariera);

printf("Wszystkie wątki zakończyły pracę.\n"); return 0; }

Przykładowy wynik powyższego programu:

Wątek 1: Rozpoczynam etap 1... Wątek 2: Rozpoczynam etap 1... Wątek 0: Rozpoczynam etap 1... Wątek 0: Dotarłem do bariery i czekam. Wątek 1: Dotarłem do bariery i czekam. Wątek 2: Dotarłem do bariery i czekam. Wątek 2: Przekroczyłem barierę, zaczynam etap 2. Wątek 0: Przekroczyłem barierę, zaczynam etap 2. Wątek 1: Przekroczyłem barierę, zaczynam etap 2. Wszystkie wątki zakończyły pracę.

W powyższym wyniku programu można wyróżnić 3 sekcje. Wątki rozpoczynają działanie, czekają aż wszystkie osiągną barierę i na koniec kończą działanie. Konkretny wynik instrukcji w każdej z sekcji może się różnić. Konkretna kolejność wewnątrz poszczególnych etapów zależy od schedulera w jądrze systemu operacyjnego.

Zobacz też bariera pamięci

Przypisy

Kategoria:Programowanie równoległe