Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Dodanie do programu zabezpieczenia thread-safe

Ostatnio zmodyfikowano 2013-02-25 21:32
Autor Wiadomość
Chlorek
Temat założony przez niniejszego użytkownika
Dodanie do programu zabezpieczenia thread-safe
» 2013-02-25 19:52:08
Piszę pewien program, który wykorzystuje kilka wątków, które operują na złożonych typach i klasach, w związku z tym zapis i odczyt pewnych wartości momentami kolidowały. Postanowiłem więc dodać zabezpieczenie, pomyślałem początkowo o użyciu CriticalSection, ale żadnego efektu nie zauważyłem. Dlatego pomyślałem jaka operacja zajmuje jak najmniej czasu procesora, wpadłem na pomysł utworzenia zmiennej bool, która będzie przetrzymywała status wykonania jakiejś części kodu w programie. Napisałem kod, który wygląda mniej-więcej tak:
C/C++
//globalna zmienna
bool state = false;

void func()
{
    while( state );
   
    state = true;
   
    // tu kod
   
    state = false;
}

Co prawda mój kod wygląda nieco inaczej w praktyce ale chodzi o pokazanie zasady działania. I teraz mam pytanie - trick daje zamierzony efekt, ale nie mam pewności co do tego czy na pewno jest to w pełni bezpieczne? W teorii zawsze gdy jakiś wątek wejdzie do funkcji i ustawi 'state' na 'true' to każdy kolejny wątek czeka do zakończenia działania pierwszego wątku w tej części kodu i to właśnie on potem znowu rezerwuje działanie na pewnych zasobach programu. Jeśli można to zrobić lepiej i efektywniej chętnie posłucham wskazówek.
P-76985
DejaVu
» 2013-02-25 20:03:50
Do takich rzeczy używa się sekcji krytycznych... mając fizycznie dwa rdzenie istnieje prawdopodobieństwo, że oba porównania while zajdą w tym samym czasie i opuszczą pętlę przez co dwa wątki będą wykonywały ten sam kod z różnymi danymi wejściowymi.
P-76986
Chlorek
Temat założony przez niniejszego użytkownika
» 2013-02-25 20:14:43
W takim razie jak poprawnie użyć sekcji krytycznych? Robiłem do tej pory to tak:
C/C++
CRITICAL_SECTION section;

int func()
{
    EnterCriticalSection( & section );
   
    // tu kod
   
    LeaveCriticalSection( & section );
}

A z InitializeCriticalSection(&section) miałem problemy - wywołanie na początku programu powodowało crash aplikacji, jedyne miejsce w którym aplikacja nie crashowała to miejsce przed EnterCriticalSection(). Może właśnie dlatego ten sposób nie działał.
P-76987
pekfos
» 2013-02-25 20:31:58
Można też użyć mutexów z biblioteki standardowej C++11.
P-76991
DejaVu
» 2013-02-25 20:35:40
No bo sekcję krytyczną trzeba jeszcze zainicjalizować. Użyj boost::scoped_lock jeżeli masz skonfigurowaną tą bibliotekę i po problemie. Albo poszukaj tutoriala do WinAPI jak obsługiwać sekcję krytyczną bądź jakiś przykład. Na pewno jest ich sporo w necie.
P-76994
Chlorek
Temat założony przez niniejszego użytkownika
» 2013-02-25 20:42:40
Do tego trzeba używać C++11, a mój projekt ma już swój czas (rozpocząłem prace ok. pół roku temu), dodatkowo mój program można nazwać dwoma programami w jednym (w zależności od argumentów pełni rolę aplikacji serwer lub klient). Wtedy zaczynając pisanie nie myślałem o tym jakiego standardu użyć, sam w sumie słabo jeszcze wtedy znałem standard C++11, a tym bardziej bibliotekę boost. Aktualnie mój projekt nie skompiluje się pod C++11, bez wielu, na prawdę wielu poprawek. Dlatego pozostaje WinAPI zamiast boosta. W przyszłości pewnie będę przepisywał program używając bibliotek ze wsparciem na różne inne platformy, ale tylko w przypadku jeśli mój program na prawdę wypali i w ogóle będzie to opłacalne.
P-76998
DejaVu
» 2013-02-25 20:44:33
Osobiście polecam zgłębiać WinAPI i trzymać się WinAPI, aniżeli pchać się na siłę w biblioteki przenośne. Doświadczenie mówi, że ważniejsze jest ukończenie projektu nad ideologie typu 'przenośność kodu', które często potrafią komplikować życie :)
P-76999
Chlorek
Temat założony przez niniejszego użytkownika
» 2013-02-25 20:51:32
Aktualnie pozostanę przy WinAPI i innych bibliotekach z których korzystam. Jednak z uwagi na to że program wykorzystuje już teraz wiele przenośnych bibliotek (między innymi OpenGL), a część programu to serwer (a wiadomo, jak serwer to dobrze byłoby dać support na linuxa). Przy okazji zapytam, jak to jest z WinSock? - coś kiedyś słyszałem, że działa również pod linuxem. To prawda?
P-77002
« 1 » 2
  Strona 1 z 2 Następna strona