Dwa wątki, jedna zmienna

Dwa wątki, jedna zmienna
0

Mam klasę, która jest opakowaniem wątku. Klasa ta zawiera prywatną zmienną typu string, która jest modyfikowana jedynie w tymże wątku. Chcę aby klasa udostępniała publiczną metodę umożliwijącą pobranie tej wartości tylko do odczytu. Czy w takim wypadku musze jakoś zabezpieczyć dostęp do zmiennej?

Przykład kodu:

Kopiuj
class Worker
{
public:
void Install() { /* start thread */ }
std::string Data() const { return data; }
private:
std::string data;
void Start()
{
while(true)
{
data = GetSomething();
}
}
}

// ...

int main()
{
   Worker w;
   w.Install();

   /* ... */
   string = w.Data();
}
kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 dni
  • Lokalizacja:Szczecin
1

Tak, musisz. Jednoczesny zapis z jednego wątku i odczyt z drugiego jest niebezpieczny. Jeżeli nie zmieniasz długości stringa to najprawdopodobniej w najgorszym przypadku dostaniesz śmieciowe dane, ale w/g standardu jest to UB i teoretycznie może stać się wszystko.


0

Długość stringa będzie stała, ale skoro twierdzisz że to UB to się z Tobą zogdzę :) jak najłatwiej zabiezpieczyć taką sytuację?

kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 dni
  • Lokalizacja:Szczecin
0

Mutex i lock_guard. Ewentualnie możesz się pobawić stringiem złożonym z atomic<char>, ale ciężko mi powiedzieć czy to by było faktycznie bezpieczne.


0

Czyli zakładam lock_guard w zmiennej która udostępnia pobranie strina oraz w zakreście w którym go modyfikuje tak ?

kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 dni
  • Lokalizacja:Szczecin
0

Tak. Wszędzie gdzie używasz stringa w jakikolwiek sposób opakowujesz go w lock_guarda na ten sam mutex.


0

Ok, niestety musze szukać alternatywy, MinGW pod Windowsem nie wspiera mutex'ów jeszcze :( a czy czyste WinAPI ma jakiś podobny mechanizm?

kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 dni
  • Lokalizacja:Szczecin
1

MinGW jak najbardziej wspiera mutexy, musisz mieć jakąś starą/wybrakowaną wersję. Jak Ci wszystko jedno to wiem, że na pewno działa wersja 4.8.2 dołączana do Qt.

Tak, WinAPI ma CriticalSection, ale jak już to bym na Twoim miejscu użył mutexów z boosta.


Zobacz pozostałe 4 komentarze
Endrju
W VS 2013 jest wystarczająco dużo C++11, żeby można tego używać. Na Windowsie GCC to straszna kupa, działa niesamowicie wolno, do tego ma sto dystrybucji i w każdej jest coś źle. Dlaczego nie może być jednej tak jak w normalnym GCC? Właśnie kolejna podałeś, której nie znałem. :-D Dobrze, że nie muszę programować pod Windowsem, bo chyba bym zmienił język. :-P
kq
Faktycznie, 2013 ma już całkiem przyzwoity support, ale niestety w naszym projekcie wymagamy więcej niż na razie jest w stanie zaoferować. Na szczęście wydajność mingw nie jest aż tak tragiczna jak mówisz, da się z tym pracować (no ale nie robię gier czy jakichś mega intensywnych obliczeń).
Endrju
Nie chodzi mi o to, że generuje zły kod. Generuje taki jak GCC. Ale kompiluje straaaaasznie wolno. No i do szału doprowadza mnie ilość tych dystrybucji.
kq
Ach. Myślę, że powolna kompilacja to bardziej problem mingw-make, który jest na windowsie bardzo nieudolny (a spróbuj wywołać kilka). Chociaż w sumie to część mingw. A co do ilości dystrybucji ja korzystam z tej dostarczonej z Qt i się nie muszę z tym... ahem, męczyć. Patrzyłem za to na ilość pamięci zużywanej przez kompilator podczas kompilacji dość zaawansowanych templatek - gcc ~300mb, vc11 ctp (vs 2012) 3gb i crash, vc12 (vs 2013) 1.2gb. Czasy były proporcjonalne, ale wiem, że to nie rzutuje na ogólną szybkość kompilacji.
Azarien
główną wadą MinGW-a jest to, że linkuje dynamicznie do msvcrt.dll, biblioteki standardowej na której zbudowano samego Windowsa, ale która zachowuje się różnie na różnych wersjach systemu, nie wspiera nowych standardów, brakuje części funkcjonalności a Microsoft wyraźnie podkreśla że jest ona wyłącznie na wewnętrzny użytek Windowsa.
0

Faktycznie, najnowsza wersja C::B korzysta jeszcze z wersji 4.7

spartanPAGE
Settings->Compiler i możesz ustawić nawet ten z VS
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 7 godzin
1

a czy czyste WinAPI ma jakiś podobny mechanizm?

critical sections, muteksy, semafory, są też lżejsze funkcje typu InterlockedIncrement, InterlockedDecrement i podobne.

0

A mam czy moge skorzystać z std::mutex w wątkach stworzonych przy pomocy funkcji CreateThread() z WinAPI?

0

@Azarien jak skorzystać w owych funkcji aby zachować bezpieczęństwo dostęptu do mojego stringa ?

kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 dni
  • Lokalizacja:Szczecin
0
KtoPytaNieBladzi napisał(a):

A mam czy moge skorzystać z std::mutex w wątkach stworzonych przy pomocy funkcji CreateThread() z WinAPI?

Tak.


0

Ok, zakładam że korzystam z critical section, wtedy kod wyglądałby mniej więcej tak:

Kopiuj
class Worker
{
public:
     void Install() { /* start thread */ }
     std::string Data() const 
    { 
         EnterCriticalSection(&CriticalSection);
         string s = data;
         LeaveCriticalSection(&CriticalSection);
         return s; }
private:
    std::string data;
    void Start()
    {
        while(true)
        {
             EnterCriticalSection(&CriticalSection); 
             data = GetSomething();
             LeaveCriticalSection(&CriticalSection);
        }
    }
    CRITICAL_SECTION CriticalSection; 
}
 
// ...
 
int main()
{
   Worker w;
   w.Install();
 
   /* ... */
   string = w.Data();
}

I mogę spać bezpiecznie że program się nie wysypie?

kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 dni
  • Lokalizacja:Szczecin
0

Nie, jeszcze musisz jednorazowo (w konstruktorze) użyć InitializeCriticalSectionhttp://msdn.microsoft.com/en-us/library/windows/desktop/ms683472%28v=vs.85%29.aspx

Albo możesz użyć boost::mutex (http://www.boost.org/doc/libs/1_55_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts) i przejść na std::mutex jak wszystkie twoje kompilatory będą go wspierały.


edytowany 1x, ostatnio: kq

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.