kommunikáció két program között

 ( FPeter84 | 2014. augusztus 17., vasárnap - 19:14 )

Sziasztok!

Két párhuzamosan futó program között szeretnék élő adatokat átadni, de amit eddig találtam az nem tökéletes, mert mind az adó mind a vevő oldalt blokkolja: az adó addig áll amíg a vevő oldal nem fut és fordítva is igaz, a vevő oldal nem lép tovább az open sorról amíg az adó oldal nem nyitja meg a pipe-ot. Fontos lenne, hogy legalább a vevő oldal akkor is továbblépjen ha éppen nincsen semmi a pipe-ban:

fifotx.c

#include
#include
#include
#include
#include

int main(int argc, char* argv[])
{
int fds[2];
char tab[BUFSIZ];
int fd, n;
int wcnt = 0;
char *myfifosrv = "/tmp/fifo";

pipe(fds);
mkfifo(myfifosrv,0666);

while(1)
{
fds[1]=open(myfifosrv,O_WRONLY);
printf("%06i\n",wcnt);
write(fds[1],"Hello World!",12);
wcnt++;
close(fds[1]);
sleep(1);
}

unlink(myfifosrv);
return 0;
}

fiforx.c

#include
#include
#include
#include
#include
#include
#include

int main(int argc, char* argv[])
{

int fds[2];
char *myfifosrv = "/tmp/fifo";

fds[0]=open(myfifosrv,O_RDONLY);

char tab[BUFSIZ];
memset(tab, 0, sizeof(tab));
read(fds[0],tab,sizeof(tab));
printf(">%s<\n",tab);

close(fds[0]);

return 0;
}

(guglival vadászott példaprogramokból indultam ki, azért olyanok amilyenek...)

Tudnátok ebben segíteni? Akár valami teljesen más kommunikációs mechanizmus is megfelelhet, nem ragaszkodok a pipe-okhoz... A legjobb az lenne, ha akár több program is olvashatná a kimenetet párhuzamosan - ez a verzió ezt se tudja, ugyan meg lehet nyitni 2x de onnantól véletlenszerű hogy éppen ki olvassa ki az adott sort, mindkettő egyszerre nem tudja...

Előre is köszönöm a segítséget!

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

posix shm+mutex -> több olvasónál ezt javaslom.

Egyébként pont-pont kapcsolathoz socketpair, nem blokkoló IO-val.

Pipe helyett inkabb unix domain socket-et javasolne'k. Az kello"en ve'dett, local kommunikaciora tokeletes (nem megy ki a nagybetus internetre) viszont ha me'giscsak ki kell menni a halozatra akkor nagyon gyorsan tudod modositani a programot. Meg persze eleve ez a "akár több program is olvashatná a kimenetet párhuzamosan" dolog is megoldodik (legalabbis nem ertem teljesen mire gondolsz, de 2-ne'l tobb program is tud socket-ekkel kommunikalni, mig pipe-ok inkabb csak 2 processz kozotti kommunikaciora jok).

Ez pl tokeletes lehet elso" peldanak, gyorsan atfutottam most.

Valamilyen message queue vagy message bus (ha a dbus úgyis fent van, akkkor érdemes lehet megismerni)?

A többiek shm/mutex vagy UNIX domain socket megoldása is jó irány, mindkettőnek megvan a maga előnye: előbbi kiváló átviteli sebessége, utóbbi a rugalmassága miatt ajánlható.

A kódodat esetleg vagy debuggold meg a gdb-vel, vagy egyszerűen helyezz el printf-eket a megfelelő helyekre (ahol valami érdekes esemény történik), pl.: printf("megnyitom a pipe-ot\n"); Egyből látni fogod, hol akad el a futás.

Azt ugye írta a leírás, hogy a két processznek egyszerre kell futnia?

Fuszenecker_Róbert

Akár a pipe is jó lehet, csak kell egy fcntl hívás is a programokba (lásd még O_NONBLOCK flag!)

Linux thread, és akkor lesz egy univerzális vázad. (+domain socket kommunikáció.)
Vagy pl ZeroMQ, ami egy faék, de ide pont jó lehet. (És nem mellesleg az is thread-et használ.)

Ja. Csak emberünknek a fő baja a blokkol (wait) IO.

Értem.
Szerintem az 1. linken említett példa nem blokkol.
Próbáld ki bátran! ;)

Non-blocking I/O kell neked (O_NONBLOCK + select/poll).

Hogy mi van az fd mögött (pipe, fifo, unix-domain socket, esetleg tcp socket), az igazából lényegtelen a működés szempontjából.

Egyébként a hibakódok ellenőrzésére még azért rá kéne gyúrni, mert ez így sok mindenre jó, de leginkább önszopatásra.

+1

Szerintem erdemes lehet erre a celra mar felhasznalni valami okosat, nem ujra feltalalni a kereket:

http://libevent.org

Ez hordozhato, eleg jo teljesitmenyu hordozhato konyvtar non-blocking io-hoz (win/linux/bsd/osx/...).

A doksija egesz jo: http://www.wangafu.net/~nickm/libevent-book/

Az elso fejezete, nagyjabol a te helyzetedbol kozeliti meg a dolgot:
http://www.wangafu.net/~nickm/libevent-book/01_intro.html

Extrakent megemlitem, hogy automatikusan jar a dologgal az is, hogy tudsz timereket es signalokat is kezelni a segitsegevel (+ van benne aszinkron dns is). Szerintem, ha nem alacsony szintu io tanulmanyozasa a celod, hanem nagyobb feladat resze, hogy a programok beszelgessenek, akkor mindenkeppen erdemes kiprobalnod.

Ha a C++ is kepben lehet, akkor hasonlo celra tudnam ajanlani az asio-t:
http://think-async.com/Asio

Az altalam ismert c++ konyvtarak kozul az egyik legokosabban tervezett. Valoszinuleg egyes reszei be fognak kerulni a kovetkezo c++ szabvanyok valamelyikebe. Annyit azert megemlitenek, hogy kicsit tobb c++ tudas kell a megertesehez, szoval, ha nem vagy otthonos a c++-ban, akkor inkabb a libevent-et probald eloszor.

Még pár dolog a named pipe-ról:

- megnyitáskor addig blokkol, míg a másik fele nincs megnyitva
- bizonyos méretű üzenet felett tördel, ha többen olvassák, igen jót fogsz szórakozni a félbeszakadt üzenetekkel
- ha garantálni akarod, hogy bizonyos méret alatt ne tördeljen, akkor posix mqueue elég használható. Többen olvashatják, de egy üzenetet egy kliens kap meg (de ez mindennemű socketnél is így van alapértelmezésben). A mqueue kb olyan mint egy kulturált postaláda: bizonyos, általad definiált levélméret alatt azt szeded ki, amit beraktál. Egyben.

Meg egyéb megjegyzések a többiek felé:
- Lehet ágyúval verébre menni (szemmel láthatóan C-ben írja a kódot, tényleg "nagy móka" a DBus C API. Illetve az eljáráshívás-szemléletű, nem message-passing).
- az ilyen ZeroMQ és egyéb javaslatokra dettó. Az a jó az IPC függvényekben, hogy hasonló logikájúak, bármikor le tudod váltani egy "komolyabbra".

Nem volt szó a SysV IPC-ről, azt érdemes elfelejteni, egy horror, ahogy kialakították :-)

Itt van pl a non-blocking-io, a select, a poll, a SIGIO... Valamint egy lehetőség arra, hogy az open se blockoljon: nyisd meg IO-ra (O_RDWR).