[Win API] Sekcje krytyczne , ochrona zmiennych

0

Dwa wątki mają dostęp do zmiennej 'a' .
Czy w tym przypadku użycie sekcji krytycznych chroni zmienną 'a' także w funkcji Fun i inny
wątek nie zmieni jej wartości na 0 po wejściu do Fun ?

//----- Globalne
int a ;
int b = 0 ;
obiektX x ;
//----- Globalne

//---------------------Wątek inny
EnterCriticalSection(&cs);
   a = 0 ;
LeaveCriticalSection(&cs);
//---------------------Wątek inny

//---------Wątek główny
EnterCriticalSection(&cs);
 a = 10 ; // <-- Ok .
x.Fun();
LeaveCriticalSection(&cs);

void obiektX::Fun()
{
         b = 1 ;

      if(a==10)  // <-- ?
    {
         b = 11 ;
    }
}
//---------Wątek główny
0

tak

0

Dzięki , właściwie to mam bardziej złożony przypadek i nie mam
pewności co do zachownia Windows .

Czy można przyjąć że zmienne które znajdą się pomiędzy wywołaniem
EnterCriticalSection(&cs);
LeaveCriticalSection(&cs);
będą bezpieczne bez względu na to czy są globalne czy znjdują się np.
w obiekcie klasy C++ ?
Np. Coś takiego , sekcja krytyczna jest składnikiem obiektu x , jeden wątek odwołuje
się do zmiennej poprzez x.a inny wątek natomiast ma tą zmienną dostępną
jako składową obiektu klasy i zmienia jej wartośc w funkcji obiektu x.Fun() :

obiektX x ;

a <- zmienna w Klasie obiektX
cs <- obiekt dla sekcji krytycznej składnik Klasy obiektX
//---------Obiekt 
void obiektX::FunJakas()
{
EnterCriticalSection(&cs);
 a = 10 ; // <-- Ok .
 Fun();
LeaveCriticalSection(&cs);
}
//---------------------------------------------------
void obiektX::Fun()
{
         b = 1 ;

      if(a==10)  // <-- ?
    {
         b = 11 ;
    }
}
//---------------------Wątek inny

// wywołanie z innego wątku na rzecz obiektu klasy obiektX 
EnterCriticalSection(& x.cs);
   x.a = 0 ;
LeaveCriticalSection(& x.cs);
//---------------------Wątek inny


//---------Wątek główny
  
       x.FunJakas() ;
0

tak, w tym przykaldzie ktory teraz podales tez jest bezpieczny. pamietaj ze tutaj nie sa wazne zmienne (a,b), tylko wazne jest kto i kiedy "przejal" dana sekcje na siebie (cs). jezeli wszystkie watki dbaja o to, zeby opakowywac enter/leave'em dostep do danego "zasobu" (zmiennej, pol obiektu, pliki, strumienia..), to nie ma szans zeby ktorys sie z ktoryms przecial. wszyscy poza jednym watkiem zasypiaja na Enter, jeden leci dalej i dopiero jak zrobi Leave to jakis inny, jeden z tych spiacych sie budzi, jak on zrobi leave to budzi sie inny itd. nie ma szans. pod warunkiem - ze wszystkie o to dbaja.

0

Dzięki za odpowiedz .
Śledziłem debugerem , jak to wygląda i niby ok.
Jednak trochę to męczące , jako że wątki są przełączane przez system czasami
trudno wyłapać czy kod zachowuje się prawidłowo , jeśli sekcje działają
wątki "nie wyrywają się z sekcji krytycznych " tak jak napisałeś .

Ciekawi mnie jeszcze taka sprawa , bez zastosowania sekcji lub złego ich zastosowania
program będzie działał w sposób losowy , czyli czasami może chodzić poprawnie dłuższy czas
i wywali się raz na kilka[naście] uruchomień . Pod debugerem podobnie .
Czy istnieją jakieś metody śledzenia takich aplikacji oprócz dziobania debugerem ,
i nadwyrężanie mózgu "równoległym myśleniem" nad zazębiającym sie kodem ...
Ewent. Czy ktoś ma jakieś własne sposoby w tym temacie .
Wiem że temat jest zbyt szeroki aby była jakaś uniwersalna metoda , ale może jakieś
cokolwiek ogólne sposoby ?
na razie wspomagam się wstawianiem funkcji Sleep() co przy wykonywaniu kodu daje większe
prawdopodobieństwo że aplikacja jeśli ma możliwość przełączy sie na inny wątek , ale to niepewna
metoda , lepsza jednak od śledzenia w kółko tego samego i obserwowania czy nastąpi zmiana wykonania na inny wątek .
Mam wrażenie że w takich aplikacjach władowanie się w jakieś bagno to bardzo prawdopodobna rzecz [green] co objawia się w praktyce tym że już kilkakrotnie zmieniłem "koncepcję" kodu i zależności
między wątkami.

0

tak.. to jest bagno i sledzi sie to tragicznie.. debuger, logi, sleepy, waity, zamrazanie wszytkich watkow w debugerze poza jednym obserwowanym itp. <ort>nieslyszalem </ort>o zadnej specjalnej metodzie sledzenia niestety..

moja metodyka w takich przypadkach jest prosta:

  • przemyslec
  • przemyslec
  • przemyslec
  • napisac program i domyslnie, do wszystkich zasobow wspoldzielonych dostep "sekcjonowac"
  • puscic. jak chodzi - super. jak nie chodzi - no to przynajmniej wiem ze sie nie przecinaja gdzies losowo
  • jak chodzi ale za wolno:
  • przemyslec
  • przemyslec
  • przemyslec
  • zastanowic sie ktora serializacja najbardziej spowalnia i sprobowac ja wyeliminowac, rezsty nie ruszac;)
0

T....,a, jeszcze miałem nadzieję na cud programowo - testowy.. [green] .

Wprawdzie metoda którą proponujesz jest mało wydajna[szczególnie jak sie TBrain wiesza] i męcząca ale lepszego
rozwiązania nie znalazłem [ i specjalnie nie liczę na więcej ].

<Fękju> , nrzie wszystko działa .... pewnie do czasu... ;-) ...
</Gejm ołwer> .. ,

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