2012-04-16 7 views
12

Jeśli każdy wątek jest gwarantowany tylko do odczytu/zapisu do określonego podzbioru tablicy, to wiele wątków może działać na tej samej (statycznej) tablicy bez odwoływania się do sekcji krytycznych, itd.?Czy można bezpiecznie uzyskać dostęp do tablic statycznych z wielu wątków?

EDYCJA - Dotyczy konkretnego przypadku macierzy typów nierejestrowanych i ich rekordów/zapakowanych rekordów.

Jeśli tak, jakieś zastrzeżenia?

Moje przeczucie jest tak, ale moje jelito może czasami być niewiarygodnym źródłem informacji.

+0

OK, wiem co to znaczy teraz. Nazwałbym to ustalonym rozmiarem, ale proszę bardzo. Nie ma znaczenia, czy rozmiar jest ustalony czy nie. Nie ma znaczenia, czy tablica ma zasięg globalny, lokalny czy klasy. Nie ma znaczenia, czy tablica jest przydzielona do sterty, czy też przydzielona do stosu. To tylko ciągły zbiór przedmiotów. –

+0

Nie, mój błąd. Nigdy nie znałem tego użycia. Myślę, że musiało to być wprowadzone po tym, jak nauczyłem się Delphi w momencie dodawania tablic dynamicznych, ponieważ wszystkie tablice wcześniej były statyczne. W każdym razie statyczne lub nie ma żadnej różnicy. –

+0

Wystarczająco fair. Jak pan twierdzi, w każdym razie nie wydaje się, aby istniał oczywisty powód, dla którego równoczesny dostęp powinien stanowić problem, ale czasami istnieją mroczne subtelności, które wprowadzają w błąd takie rzeczy. Czasami miło być podwójnie pewnym. –

Odpowiedz

8

Załóżmy, że:

  1. Masz jedno wystąpienie tablicy (statyczne lub dynamiczne) oraz
  2. Elementy tablicy są typy wartości czystego (czyli nie zawierają żadnych odniesień), a
  3. Każdy wątek działa na rozłącznych pod-tablicach i
  4. Nic innego w systemie nie zapisuje w tablicy, gdy działają na niej wątki.

Przy tych warunkach, które, jak sądzę, są spełnione przez strukturę danych i wzór wątków, wszystkie algorytmy są wątkowo bezpieczne.

+0

Przypuszczam, że tak by było również w przypadku obiektów typu odniesienia, jeśli odniesienia do tego samego obiektu są zagwarantowane, że istnieją tylko w pojedynczej podrzędnej (tj .: brak wspólnych odniesień współużytkowanych między rozłącznymi pod-tablicami). –

+2

@J ... Tak, to prawda. Tak długo, jak każdy wątek działa na danych prywatnych do tego wątku, algorytmy są wątkowo bezpieczne. –

+0

@DavidHeffeman, Czy stan # 4 jest naprawdę potrzebny? Jaka jest różnica między głównym wątkiem lub innym procesem zapisującym do tablicy a działającymi na nim wątkami? – Arnold

7

Nie, to nie może być bezpieczne w przypadku niektórych sytuacji.

Widzę co najmniej dwa powody.

1. To będzie zależeć od statycznej zawartości tablicy.

Jeśli użyjesz niezwiązanych z numerem typów (np. double, integer, bytes, shortstring), w większości przypadków nie będzie problemu (przynajmniej jeśli dane są odczytywane/tylko).

Ale jeśli używasz typów zliczanych referencyjnie (takich jak string, interface lub zagnieżdżona dynamiczna tablica), musisz zadbać o bezpieczeństwo wątków.

Czyli:

TMyType1: array[0..1] of integer; // thread-safe on reading 
TMyType2: array[0..1] of string; // may be confusing 

Dodatkowa nota: jeśli string jest w rzeczywistości wspólną wśród niektórych podgrup części statycznej tablicy, można mieć licznik odniesienia mylić. Chyba że jednoznacznie nazwiesz UniqueString() dla każdego z nich (w sekcji krytycznej podejrzewam). W przypadku tablicy double lub integer ten problem nie wystąpi.

2. To będzie zależeć od współbieżności dostępu

odczytu należy wątku bezpieczne, nawet dla odniesienia liczone typu, ale równoczesny zapis może być mylące. W przypadku niektórych przypadków losowych, w szczególności na wielordzeniowym procesorze, mogą występować problemy z GPF.

Niektóre bezpieczne wdrożenie może być:

  • Stosować sekcje krytyczne (mniejszy, jak to możliwe, aby zmniejszyć narzut) lub inne konstrukcje zabezpieczające;
  • Użyj Kopiuj-do-zapisu lub prywatnej kopii na wątek treści, aby mieć pewność;
  • Najnowsza uwaga (nie na temat bezpieczeństwa, ale wydajności): udostępnianie macierzy między wieloma procesorami może prowadzić do nakładania kar z powodu synchronizacji pamięci podręcznej między procesorami. Wydajność jest czasami o wiele lepsza, gdy używasz oddzielnych tablic, upewniając się, że ich okno buforowania L1 nie będzie współużytkowane przez procesory.

Należy pamiętać, że takie problemy mogą być koszmarem do debugowania po stronie klienta: problemy z wieloma wątkami mogą występować losowo i są bardzo trudne do śledzenia. Im bezpieczniejsze, tym lepiej, chyba że masz jednoznaczne i sprawdzone problemy z wydajnością.

Dodatkowa uwaga: Dla konkretnego przypadku statycznej macierzy podwójnej, z podelementem macierzy, do której dostęp ma tylko jeden wątek, jest bezpieczny dla wątków. Ale nie ma absolutnej zasady bezpieczeństwa nitki we wszystkich sytuacjach, nawet dla statycznej tablicy. Gdy tylko użyjesz typów zliczających referencje lub niektórych wskaźników, możesz mieć problemy losowe.

+0

Dobra uwaga - powinienem był dokładnie opisać typ tablicy. W tym przypadku elementy są zapakowanymi zapisami podwójnymi (które moim zdaniem powinny być bezpieczne). –

+0

Ta odpowiedź jest po prostu błędna moim zdaniem. Zadaniem tego pytania jest to, że każdy wątek działa na rozłącznych pod-tablicach. I działa na nim tylko wątek będący właścicielem każdej z tablic podrzędnych. To jest bezpieczne dla wątków bez względu na typ elementu. –

+0

@DavidHeffernan - również dobry punkt. Tablice odniesionych liczonych obiektów zawierają tylko wskaźniki, tak? –

Powiązane problemy