Właściwe przypadki użycia Sekcji Krytycznych

0

Cześć,
chciałbym wreszcie usystematyzować swoją wiedzę na temat użycia i przypadków konieczności użycia sekcji krytycznych w wypadku aplikacji wielowątkowych.
Pozwolicie, że zadam parę mega podstawowych pytań. Wiem, ze to podstawy podstaw ale prosze badzcie delikatni ;)

Załóżmy, że mam tablicę polaczenia, zawiera ona rekordy z id uzytkownika oraz (na potrzeby przykladu) socket do komunikacji w sieci:

TKlient = record
id:integer;
gniazdo:socket;
end;
  1. Jezeli chce tylko wyslac informacje do konkretnego klienta to czy musze uzyc sekcji krytycznych?
polaczenia[10].gniazdo.SendMessage('wiadomosc');

czy

CS.Enter;
try
polaczenia[10].gniazdo.SendMessage('wiadomosc');
finally
CS.Leave;
  1. Tak samo jezeli chce np tylko pobrac dane z tablicy (zakladamy, ze jednak az tak dynamicznie sie nie zmieniaja)
var
klient:TKlient;
(...)

klient:=polaczenia[10];

czy jednak

var
klient:TKlient;
(...)
CS.Enter;
try
klient:=polaczenia[10];
finally
CS.Leave;
  1. Jezeli usuwam jakis element to zakladajac, ze w trakcie usuwania jakis watek moze realizowac odczyt odpowiedz nasuwa sie sama. Tylko czy faktycznie nie wystarczy
polaczenia[10]:=nil;

a konieczne i zgodne z jakimis powszechnymi zasadami jednak:

CS.Enter;
try
polaczenia[10]:=nil;
finally
CS.Leave

Zakladajac, ze w mojej aplikacji jest kilka watkow wysylajacych informacje do polaczonych klientow to czy nie bedzie zbyt opoznialo uzycie jednej sekcji krytycznej i blokowania calej tablicy zeby wyslac info jednemu klientowi?

pozdrawiam!

3
  1. Jezeli usuwam jakis element to zakladajac, ze w trakcie usuwania jakis watek moze realizowac odczyt odpowiedz nasuwa sie sama. Tylko czy faktycznie nie wystarczy
polaczenia[10]:=nil;

TKlient to rekord, a Ty podajesz Nil - to raczej przykład z głowy, mam rację?

Co do tematu, weź to na zdrowy rozsądek - skoro modyfikujesz jakieś współdzielone dane, do których w tym samym czasie może próbować uzyskać dostęp inny wątek, to musisz na tę chwilę ten dostęp wstrzymać.

3

Ad 1: prawie na pewno będziesz musiał w tym wypadku użyć sekcji krytycznych - lecz to zależy jeszcze od samej biblioteki socketa: być może w niej już jest taki mechanizm zaimplementowany.

Ad 2, 3: jeśli miałbyś tablicę typu prymitywnego (np. tablica stringów, integerów, wskaźników (w tym referencji do obiektów) etc.), wtedy operacja byłaby atomowa (wykonywana w jednym cyklu zegarowym, zatem bez potrzeby nakładania blokady) - Ty jednak masz tablicę rekordów, a FPC podczas takiego przypisania generuje głęboką kopię rekordu, zatem przestaje to być atomowe i wymagana jest sekcja krytyczna.

3

Każdy dostęp do zasobu współdzielonego przez wiele wątków musisz wykonać z zapewnieniem chwilowej wyłączności dostępu do zasobu przez wątek .

Sekcja krytyczna, to tylko jeden z mechanizmów , chyba najprostszy w użyciu przy współdzielonym dostępie w obrębie jednej aplikacji. Przy współdzieleniu dostępu do zasobu przez różne aplikacje są mechanizmy takie jak np. muteksy działające na poziome systemu a nie aplikacji.

0
grzegorz_so napisał(a):

Każdy dostęp do zasobu współdzielonego przez wiele wątków musisz wykonać z zapewnieniem chwilowej wyłączności dostępu do zasobu przez wątek .

Nie do końca jest to prawda. Jeśli załóżmy, że dwa wątki tylko i wyłącznie czytają jakiś zasób, to nie trzeba tutaj nic synchronizować. Ale jeśli już jeden z nich może zmodyfikować dany zasób, to wtedy jak najbardziej synchronizacja musi być.

1 użytkowników online, w tym zalogowanych: 0, gości: 1