Dariusz Bujak

Dariusz Bujak Student, młodszy
programista JAVA,
C++

Temat: C++ i watki

Witam, mam taka klase


#pragma once
#include<string>

using namespace std;
class P
{
private:
unsigned int id;
string portCOM;
bool transmission;
public:
P(unsigned int, string);
~P(void);
unsigned int getId(void);
string getPortCOM(void);
bool isTransmission(void);
void setTransmission(bool);
};



i teraz tak w jednym watku chodzi sobie petelka która caly czas sie kreci i sprawdza mi wartość isTransmission jezeli jest rowna false wtedy uruchamia sie mowy watek do którego przekazuje zmienna za pomoca referencji element z tablicy vector<P> element klasy P. I teraz na starcie nowy watek ustawia wartość setTransmission(true) a po zakonczeniu ustawia setTransmission(false). Wiec mam do doświadczonych ludzi w programowaniu wielo watkowym czy musze ustawić sekcje krytyczna dla tak przekazywanego obiektu P?Dariusz Bujak edytował(a) ten post dnia 12.06.12 o godzinie 21:16

konto usunięte

Temat: C++ i watki

Jeżeli dobrze rozumiem, to z kolekcji vector<Parkomat> może jednocześnie korzystać kilka wątków? Przynajmniej 2? Jeżeli tak, to sugerowałbym sekcję krytyczną, albo, co w tak prostym kodzie jest moim zdaniem lepszym rozwiązaniem, implementacja prostego semafora :)
Dariusz Bujak

Dariusz Bujak Student, młodszy
programista JAVA,
C++

Temat: C++ i watki

No właśnie jest tak że ten jeden wątek sprawdza w każdym elemencie vector<P> metode isTransmission() a jeżeli jest wartość false to tworzy nowy watek i przekazuje przez referencje jeden obiekt z vector<P> i tam on na niej pracuje i przy okazji zmienia wartośc isTransmission() na true dzieki tem jest on wyłączony i do czasu zmiany wartości na isTransmission() na false nie bedzie tworzone dla tego obiektu z vector<P> nowy watek.

Jeżeli proponujesz zakładanie sekcji krytycznej to czy jest możliwość zakładania jej tylko dla danego elementu z vector<P> a nie dla całej kolekcji? Czy założenie sekcji krytycznej na całej kolekcji równało by sie z zrezygnowaniem wielowątkowości?Dariusz Bujak edytował(a) ten post dnia 12.06.12 o godzinie 21:16
Karim Agha

Karim Agha Software Engineer

Temat: C++ i watki

Synchronizacji uzywaj tylko wtedy kiedy wiecej niz jeden watek zapisuje do kolekcji/obszaru pamieci. Jesli jednak kilka watkow tylko czyta albo kilka watkow czyta i jeden zapisuje to nie potrzebna jest zadna synchronizacja.

konto usunięte

Temat: C++ i watki

Karim Agha:
Jesli (...) kilka watkow czyta i jeden zapisuje to nie potrzebna jest zadna synchronizacja.

A co jeżeli wątek "zapisujący" wywoła clear() podczas gdy wątek "czytający" akurat wywołuje metodę (oznaczoną jako const, więc kwalifikującą się jako czytanie ;)) na obiekcie będącym elementem kolekcji?
IMO synchronizacja jest potrzebna zawsze gdy istnieje wątek, który może zmodyfikować stan obiektu.Maciej O. edytował(a) ten post dnia 12.06.12 o godzinie 12:17
Karim Agha

Karim Agha Software Engineer

Temat: C++ i watki

Maciej O.:
Karim Agha:
Jesli (...) kilka watkow czyta i jeden zapisuje to nie potrzebna jest zadna synchronizacja.

A co jeżeli wątek "zapisujący" wywoła clear() podczas gdy wątek "czytający" akurat wywołuje metodę (oznaczoną jako const, więc kwalifikującą się jako czytanie ;)) na obiekcie będącym elementem kolekcji?
IMO synchronizacja jest potrzebna zawsze gdy istnieje wątek, który może zmodyfikować stan obiektu.

Masz racje. W takich przypadkach zalecane jest nie blokowanie calej kolekcji z powodu pracy jednego watka na niej, a raczej pracowaniu na lokalnej kopii. Watek czyta - zapisuje sobie to co chce przez najblizszy czas przerobic z kolekcji i pyta o kolejne jak skonczy.

konto usunięte

Temat: C++ i watki

Karim Agha:
Masz racje. W takich przypadkach zalecane jest nie blokowanie calej kolekcji z powodu pracy jednego watka na niej, a raczej pracowaniu na lokalnej kopii. Watek czyta - zapisuje sobie to co chce przez najblizszy czas przerobic z kolekcji i pyta o kolejne jak skonczy.

To też nie zawsze dobrze zadziała:
Po pierwsze - obiekt może być zmieniony przez drugi wątek w momencie gdy pierwszy tworzy jego lokalną kopię. Debugowanie crashy spowodowanym czymś takim nie należy do najprzyjemniejszych czynności na świecie ;)

Po drugie - wszystko zależy od sytuacji. Jeżeli wątek 1 przetwarza kopię obiektu a drugi go w tym czasie zmodyfikuje - wyniki uzyskane przez wątek 1 mogą "nie pasować" do całości operacji na kolekcji. Jeżeli kolekcja jest tylko zbiorem jednostkowych, nie powiązanych ze sobą obiektów wtedy zazwyczaj jest to akceptowalne ale nie zawsze masz taką gwarancję.

BTW, polecam obejrzenie http://channel9.msdn.com/Events/GoingNative/GoingNativ... . Materiał co prawda koncentruje się na c++ 11 ale przy okazji wypunktowuje najczęściej popełniane błędy w aplikacjach wielowątkowych. Także te nietrywialne.
Dariusz Bujak

Dariusz Bujak Student, młodszy
programista JAVA,
C++

Temat: C++ i watki

Ok, widzę że temat sie rozszerzył to bardzo fajnie:). Wiec z tego co zrozumiałem akurat w moim przypadku nie trzeba zakładać synchronizacji, to miło. Aplikacja hula non stop przez dwa dni i nie zaobserwowałem żadnych problemów. Niestety do czasu jak postanowiłem przekazać przez wskaźnik połączenie do bazy postgresa do każdego wątku no i po pierwszym uruchomieniu gdy wątki zaczęły robić zapytanie do bazy program sie sypnął z wiadomych względów. Dlatego postanowiłem przy tworzeniu nowego elementu w kolekcji vector<p> utworzyć tak ze połączenie dla nowego obiektu tak żeby watek który bedzie tworzony dla elementu z z tejże kolekcji miał własne połączenie do bazy. Potem (a właściwie teraz :) ) zastawiam sie co by było jak bym nie przekazywał tego połączenia przez wskaźnik a przez kopie dla każdego obiektu z kolekcji? Czy też w tym wypadku mogło by dojść do błędów bez zakładania sekcji krytycznej?
Karim Agha

Karim Agha Software Engineer

Temat: C++ i watki

Maciej O.:

BTW, polecam obejrzenie http://channel9.msdn.com/Events/GoingNative/GoingNativ... . Materiał co prawda koncentruje się na c++ 11 ale przy okazji wypunktowuje najczęściej popełniane błędy w aplikacjach wielowątkowych. Także te nietrywialne.

Byłem na tej konferencji osobiscie :)
Karim Agha:
Masz racje. W takich przypadkach zalecane jest nie blokowanie calej kolekcji z powodu pracy jednego watka na niej, a raczej pracowaniu na lokalnej kopii. Watek czyta - zapisuje sobie to co chce przez najblizszy czas przerobic z kolekcji i pyta o kolejne jak skonczy.

To też nie zawsze dobrze zadziała:
Po pierwsze - obiekt może być zmieniony przez drugi wątek w momencie gdy pierwszy tworzy jego lokalną kopię. Debugowanie crashy spowodowanym czymś takim nie należy do najprzyjemniejszych czynności na świecie ;)

Też prawda - użyłem za mocnego skrótu myślowego w mojej pierwszej wypowiedzi (compare-and-swap to jednak dalej synchronizacja w pewien sposob) ;)
Po drugie - wszystko zależy od sytuacji. Jeżeli wątek 1 przetwarza kopię obiektu a drugi go w tym czasie zmodyfikuje - wyniki uzyskane przez wątek 1 mogą "nie pasować" do całości operacji na kolekcji. Jeżeli kolekcja jest tylko zbiorem jednostkowych, nie powiązanych ze sobą obiektów wtedy zazwyczaj jest to akceptowalne ale nie zawsze masz taką gwarancję.

I znowu sie zgadzam. Za bardzo uproscilem swiat odpowiadajac za pierwszym razem (j/w CAS) ;)Karim Agha edytował(a) ten post dnia 15.06.12 o godzinie 17:20

konto usunięte

Temat: C++ i watki

Ciekawa dyskusja. Wielowątkowość to przyszłość! Zegary procesorów stanęły w miejscu i nie bardzo widać, aby nadal tendencja wzrostowa, którą przewidział Moore utrzymała się. Sporo np. programów graficznych wciąż pracuje na jednym rdzeniu, a można by przyspieszyć algorytmy znacznie, gdyby programiści lepiej znali się na wątkach i synchronizacji...
Przemysław Tomaszewski

Przemysław Tomaszewski Senior Developer,
Compuware Sp. z o.o.

Temat: C++ i watki

Maciej O.:
Karim Agha:
Jesli (...) kilka watkow czyta i jeden zapisuje to nie potrzebna jest zadna synchronizacja.

A co jeżeli wątek "zapisujący" wywoła clear() podczas gdy wątek "czytający" akurat wywołuje metodę (oznaczoną jako const, więc kwalifikującą się jako czytanie ;)) na obiekcie będącym elementem kolekcji?
IMO synchronizacja jest potrzebna zawsze gdy istnieje wątek, który może zmodyfikować stan obiektu.

Uważam, że ostatnie zdanie powinno brzmieć: "GENERALNIE synchronizacja jest potrzebna gdy istnieje wątek, który może zmodyfikować stan obiektu." Oznacza to, że są przypadki, w których nie ma potrzeby stosowania mechanizmów synchronizacyjnych. Za taki można podać przykład Dariusza, gdzie:
- mamy jeden wątek monitorujący pracę pozostałych (nazwijmy je workerami)
- monitoring polega na przeglądaniu wektora zawierającego obiekty klasy P - każdy z tych obiektów jest współdzielony (właściwie jego część) przez dokładnie 2 wątki z czego jeden tylko czyta (wątek monitorujący) - a drugi tylko pisze (worker)
- jeżeli jakiś worker (nazwijmy go A) zakończy pracę używa "sygnału" ustawiając flagę transmission na "false", wtedy wątek monitorujący tworzy i uruchamia nowego workera (A') przydzielając mu obiekt klasy P używany wcześniej przez workera A.

Zakładając że:
- zawartość wektora nie zmienia się podczas pracy workerów, tzn. że jego modyfikacje są przeprowadzane gdy nie jest aktywny żaden worker (inicjalizacja i niszczenie),
- operacje wykonywane na zasobie są atomowe - zmiana wartości parametru typu bool z reguły jest (powinno się zadeklarować taką zmienną jako volatile),
- na jednym zasobie operacje zapisu są wykonywane tylko przez jeden wątek,
- jest zapewnione iż po ustawieniu flagi transmission na "false" wątek workera nie korzysta z przydzielonego mu obiektu P,

to synchronizacja jest zbędna.

Następna dyskusja:

apel ... czy osoby nie zwi...




Wyślij zaproszenie do