W utworzonym przeze mnie systemie tworzenia oprogramowania OUX/C+ wykorzystuję ‹zadania› asynchroniczne, które są wątkami systemowymi mającymi dodatkowe funkcjonalności. W przykładowym wątku rysowania korzystam z danych globalnych procesu, w którym wątek jest uruchomiony, w następujący sposób w pętli:
- Oczekiwanie na ‹raport›, po otrzymaniu którego…
- Czytanie danych globalnych procesu i obliczenia bez ich modyfikacji.
- Jednorazowa zamiana zmiennej globalnej procesu.
Stąd konieczne jest synchronizowanie na dostępie do danych pomiędzy takim wątkiem a pozostałymi wątkami w procesie.
Obecnie synchronizuję przez utworzenie sekcji krytycznej (z użyciem ‘muteksu’): w takim wątku – wokół punktu 2 i 3, a w innych wątkach wokół bloków modyfikacji danych globalnych procesu.
W tym przykładzie współdzielone dane globalne procesu są wyszczególnione: są to trzy zmienne (w skrócie – “displays”, “windows” i “objects” graficzne w oknie) będące wskaźnikami do struktur zarządzanych przez ‹menedżerów› (rodzaj obiektowości w C+). Dlatego można wskazać, w których procedurach ‹menedżera› następuje modyfikacja: w procedurach dodawania ‘display’, ‘window’ i ‘object’ oraz w procedurach usuwania. Nie trzeba się przejmować modyfikacją zawartości obiektu, ponieważ zawsze zachowuje on wewnętrzną integralność danych w modelu podzielonej na ‹zadania› odpowiedzialności ich ustawiania‐czytania.
Pytanie jest następujące: gdzie umieszczać sekcje krytyczne w innych wątkach? Czy wewnątrz procedur modyfikacji zmiennych globalnych czy na zewnątrz, wokół bloków wołających te procedury w procedurze np. “main”?
I czy w ogóle to jest odpowiednie podejście do synchronizacji wątków mających dostęp do wyszczególnionych danych globalnych procesu?
⁂
Wydaje się, że lepiej jest umieszczać sekcje krytyczne wokół bloków wołających procedury (na zewnątrz) w procedurze “main” i procedurach ‹zadań›, ponieważ:
- Blokowanie wewnątrz, we fragmencie procedury takiej jak dodającej ‘display’ lub ‘window’ dawałoby teoretycznie (ponieważ i tak wątek czeka na ‹raport›) możliwość bezużytecznego wykonania się wątku rysującego, gdyż ‹zadania› zmieniające stan ‘objects’ nie są w tym momencie wykonywane.
- Tuż po dodaniu ‘display’ lub ‘window’ — ‘objects’ jeszcze nie są utworzone.
- Dodawanie ‘objects’ i tak wymaga blokowania na zewnątrz ze względu na specyfikację wywołań, a przerysowywanie niekompletnego zestawu ‘objects’ byłoby mylące dla użytkownika.