shared memory vs named pipes

0

Cześć,
umiem dość dobrze (czyste) C++. Obecnie zacząłem uczyć się WinApi. Chciałbym zrobić niedługo dwie aplikacje, które będą się między sobą komunikować na jednym komputerze. Głównie będą przekazywane liczby typu double.
Chciałem się teraz zapytać co jest łatwiejsze do opanowania (mniej problematyczne): named pipes czy shared memory?
Trochę już o tym czytałem, ale nie jest to dla mnie prosty temat :(

0

Zależy w jaki sposób to będzie przekazywane i odbierane.

  • jak często zapisywane?
  • jak często odczytywane?
  • czy zawsze taka sama ilość danych?
  • czy procesy muszą być zsynchronizowane?
0
_13th_Dragon napisał(a):

Zależy w jaki sposób to będzie przekazywane i odbierane.

  • jak często zapisywane?
  • jak często odczytywane?
  • czy zawsze taka sama ilość danych?
  • czy procesy muszą być zsynchronizowane?

Ad. 1) zapis danych odbywałby się od 1 sekundy do 1 minuty.
Ad. 2) odczyt danych j.w. - po zapisaniu danych przez pierwszą aplikację druga powinna je odczytać, przetworzyć i odesłać wynik do pierwszej aplikacji.
Ad. 3) tak, zawsze taka sama ilość danych
Ad. 4) Tak, jeśli dobrze rozumiem to oba procesy powinny działać w sposób zsynchronizowany (jak w punkcie 2)

0

W takim razie shared memory.

0

Okey, dzięki. Poczytam trochę o tym i zobaczymy co mi wyjdzie ;-)
pozdrawiam

0

Jeśli chodzi tylko o wymianę liczby Double to IMO jest to armata na muchę - najszybciej pójdzie komunikatami.

0
_13th_Dragon napisał(a):

W takim razie shared memory.

Na jakiej podstawie tak twierdzisz? SM jest dobra, kiedy lokalnie przesyłane są duże ilości danych i wymagana jest duża wydajność. Tu nie ma ani jednego, ani drugiego, a za to zachodzi potrzeba synchronizacji, więc dwa potoki nazwane do dwukierunkowej komunikacji będą moim zdaniem dużo bardziej odpowiednim narzędziem.

0
ŁF napisał(a):
_13th_Dragon napisał(a):

W takim razie shared memory.

Na jakiej podstawie tak twierdzisz?

Wysyłanie:

while(true)
  {
   if(!shared->have)
     {
      cin>>shared->value;
      shared->have=true;
     }
  }

Odbiór:

while(true)
  {
   if(shared->have)
     {
      cout<<shared->value;
      shared->have=fasle;
     }
  }

Czy dasz rady z dwoma potokami zrobić prostszy wysyłanie/odbiór ?

0

Has, nie have.
Zapomniałeś dodać synchronizację.
Nie zainicjowałeś obiektu.
Gdzie jest definicja klasy?

Parafrazując trochę Twój kod:
serwer:

while(true)
{
  pipe->SendValue(someValue);
  answer = pipe->GetValue();
}

klient:

while(true)
{
  answer = pipe->GetValue();
  pipe->SendValue(someValue);
}

Jak widać równie prosty, jeśli "zapomni się" o kilku rzeczach.

0
ŁF napisał(a):

Has, nie have.
Jak zwał tak zwał.

ŁF napisał(a):

Gdzie jest definicja klasy?
A tak trudno się domyślić:

struct  Shared { double value; bool have; } *shared;
ŁF napisał(a):

Nie zainicjowałeś obiektu.
shared=(Shared*)GetSharedMemory(...,sizeof(Shared));

ŁF napisał(a):

Zapomniałeś dodać synchronizację.
Właśnie jest synchronizacja, patrz uważnie, zaś u ciebie synchronizacja nie podana. Jak dodasz synchronizacje to u ciebie będzie bardziej skomplikowane.

0

Nie ma synchronizacji u Ciebie. Jeśli oba programy naraz będą chciały cokolwiek zapisać, to jeden z nich się wywali. Nawet jeśli to nie nastąpi, to zapisanie dwóch elementów nie jest operacją atomową, więc może się zdarzyć tak, że pierwszy program ustawi true, drugi właśnie odczytał dane i ustawił false, pierwszy zapisze wartość, a potem się zakleszczą. Może się też trafić tak, że zostanie odczytana połowa nowej wartości, a połowa starej. Same problemy :-)
Potoki zapewniają synchronizację "out of the box", a szczególnie model half-duplex. Zgadzam się, że model pamięci współdzielonej może wyglądać na łatwiejszy, jednak kiedy obie strony zapisują pojawia się problem synchronizacji, który musi być rozwiązany odrębnym mechanizmem.
Nie ma czegoś takiego jak "jak zwał tak zwał". Jeden element, więc liczba pojedyncza.

0

@ŁF, popatrz jeszcze raz uważnie.

struct  Shared { double value; bool have; } *shared;

Wysyłanie:

while(true)
  {
   if(!shared->have)
     {
      cin>>shared->value;
      shared->have=true;
     }
  }

Odbiór:

while(true)
  {
   if(shared->have)
     {
      cout<<shared->value;
      shared->have=fasle;
     }
  }

Jeżeli wartość shared->have==false:

  1. Odbiór nie da rady nic zrobić ponieważ nie wejdzie w if(shared->have)
  2. Natomiast wysyłanie wejdzie do pętli wczyta zmienną i spokojnie przestawi shared->have na true

Jeżeli wartość shared->have==true:

  1. Wysyłanie nie da rady nic zrobić ponieważ nie wejdzie w if(!shared->have)
  2. Natomiast odbiór wejdzie do pętli wyświetli zmienną i spokojnie przestawi shared->have na false

Wszystko pęknie działa ponieważ operacje shared->have=fasle; oraz shared->have=true; są atomowe.

0

Dziękuję wam bardzo za waszą pomoc i ciekawą dyskusję ;-).
Szczególnie Tobie _13th_Dragon dziękuję za ciekawy i bardzo prosty przykład! Nie wiedziałem, że to aż tak proste :P.
Mam jednak pytanie dot. zastosowanej przez Ciebie funkcji GetSharedMemory - czy możesz mi powiedzieć w której ona jest bibliotece i gdzie mogę o niej ewentualnie przeczytać? Wrzuciłem ją w google, ale nic sensownego znaleźć nie mogę...
Z góry dziękuję za pomoc!

0

Ohh, no tak, zapomniałem, że rodzaj systemu może mieć znaczenie ;-)
Czyli rozumiem, że podana przez Ciebie nazwa jest tylko przykładowa i jej nazwa ma tylko symbolizować efekt jej działania?
Mi chodziło o Windowsa i coś czytam właśnie o funkcji typu createfile oraz createfilemapping etc. Rozumiem, że to dobry kierunek poszukiwań? ;-)
pozdrawiam

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