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ások
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.)
Szerintem gépen belül simán IPC shared memory.
Itt van 1-2 példa:
http://www.cs.cf.ac.uk/Dave/C/node27.html
http://beej.us/guide/bgipc/output/html/singlepage/bgipc.html#shmsam
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).