[MEGOLDVA] Ötleteket kérnék processzek közti kommunikációban

Fórumok

Üdv!

A következő feladatom lenne (sajnos a körülmények adottak, tehát eltérni nem nagyon tudok):

Van n db. processz, Linux rendszeren, (n<=64), melyek egymástól függetlenül, tehát nem fork()-kal jönnek létre (vagyishogy
valamilyen szinten mégis, mert fork-execv párossal születnek, de ugyebár az execv felülmos minden előéletet. Még mielőtt kérdenétek, sajnos az execv-től nem tudok megszabadulni :( ).

Ezek közt kéne olyan csatornát létrehoznom, melyen bármely két processz tudna egymással kommunikálni.

A jelenlegi megoldásom a következő: a sysv ipc message queue-it használom (msgsnd, msgrcv), minden processz generál egy kulcsot magának (ftok-kal)
egy olyan "algoritmus" szerint, melyet ők ismernek, ezért aztán bármelyik processz tudja generálni egy másiknak a kulcsát, és tud neki üzenni. Ennek van egy hátránya (meg több másik is): döglassú.

Ilyenre írták más fórumokon (ugyanis google-n már nézelődtem), hogy használj socketpair()-t.
A bánatom az, hogy ehhez az kell, hogy a fileleíró-t el kéne juttatni az egyik processztől a másikig. Namost ennek is utánanéztem, le is írják, hogy socketen keresztül vígan lehet fileleírót küldeni. Persze. Csak nekem pont ennek a socketnek a létrehozása a probléma...

Még gondolkodtam a named socket-eken is, csak mondjuk ha van 64 processzed, és mindegyik beszélni akar mindegyik másikkal, az 64*63/2 db file... (ha jól számolok) és ez nem tűnik annyira jó megoldásnak.

Azt is gondoltam, hogy esetleg argumentumként adok át valamit az új processz létrehozásakor, ennek csak az az egy baja, hogy úgy kéne megírni a programot, hogy ne legyenek benne "speciális" argumentumok. (tulajdonképpen nem egy programról van szó, hanem egy programkönyvtárról).

A legtöbb ötletemnek az a baja, hogy kompatibilisnek kell maradnom egy másik API-val, amelynek ugyan a forrása megvan, tehát bele tudok nézni, mit hogy csinál, de sajnos nem portolható rendesen egy általános PC-re, mert egy nagyob spéci hardveren van.

Előre is köszönök minden javaslatot.

Hozzászólások

Azt nem lehet, hogy csinalsz egy keystone programot, ami csak routolja az uzeneteket? Akkor mindossze 64 socket kellene es egy plusz processz. Nem sokkal lassabb, mint az osszevissza kommunikacio, de legalabb egyszerubb.

Nem, a fileleíró nem a file neve, hanem egy azonosító szám, mely a process által megnyitott fileok táblájában mutat valahová (nagyon durván fogalmazva). Szóval a lényeg, hogy ez processfüggő, tehát nem globális az egész rendszerre nézve. Tehát ha csak simán átküldeném ezt a számot egy másik processnek, ott nem lenne értelmes, vagy egy másik megnyitott file-t jelölne. (tehát lehet, hogy a 100-as fileleíró az egyik processnél a megnyitott "kakukk.out" file-t jelöli, a másik processnél meg érvénytelen, a harmadiknál meg valamilyen másik filet). Egyik sem kívánt működés.

Egyébként egy nem nevesített socketnek nincs fileneve, de fileleírója az van, annál fogva tudsz rajta küldözgetni.

Lényegében a fileleíró az az, amit a write(), read() függvényeknél meg kell adnod.

Persze javítsatok ki, ha pontatlan vagyok, netántán tévedek.

---
WGábor

UNIX socket egy kontroll processzel ami konkretan csak az uzenetek "rutolasaval" foglalkozik ? (Plusz non-block socketek ahol e-poll-lal varsz esemenyre, hogy sebessege is legyen.)

---
pontscho / fresh!mindworkz

Nem tudom, milyen üzeneteket akarsz küldözgetni, de ha egy integer elég, akkor használj real time signalokat.
Előnyök:
1. gyors
2. garantált kézbesítés (nem vesztik el, mint pl egy posix signal)
3. minden processznek van külön fifo queue-ja, nem kell vele foglalkoznod
Hátrány:
1. max integert lehet átadni.

Lehet, hogy hülyeség, de TCP/IP nem lenne jó? Minden processz figyel egy előre meghatározott porton.

Hát amit te akarsz, az gyakorlatilag egy p2p megvalósítás lene localhoston. :)
Inkább fordulj abba az irányba, hogy egy egyszerű, max. 100 soros programot csinálj, ami nyit egy UNIX domain socketet, és ahhoz kapcsolódik a többi program, és ez adogatja át az üzeneteket.
Így könnyedén meg tudsz valósítani olya, hogy egy processz akár többnek is elküldje azonnal az üzenetet, vagy akár mód lehessen "broadcast" küldésre, stb.stb.
Én így állnék neki, elvégre az UNIX domain socketeket is erre találták ki.

Socket, lehet unix-domain vagy tcpip, igazából halál mindegy, mert socketpair-rel kell létrehozni a szülő processz-ben, és a gyereknek "odaörököltetni" az általa használandó végét a párnak. Van fcntl flag (FD_CLOEXEC), amivel el lehet érni, hogy az adott fd-t az execnél ne csukja be a szülő, így egy extra nyitott fd-t kap a gyerek, amin keresztül a szülővel tud beszélgetni. A szülőtől aztán mondjuk bármelyik gyerek ezen tud kérni egy socketet valamelyik másik gyerekhez, amit a szülő csinál socketpair-rel, majd a megnyitott socket két végéhez tartozó fd-ket a két gyereknek leküldi (man cmsg), így onnantól kezdve ők ezen direktben tudnak egymással beszélgetni.

Magyarul minden gyereknek lesz egy socketja a szülőhöz, plusz minden gyerekhez, akivel beszélgetni akar.

PVM esetleg?

--
"Az a szóbeszéd járja Amerikában, hogy két intelligens faj létezik a földön: emberek és magyarok." by Isaac Asimov

A leiras alapjan feltetelezem, hogy valami uzenet alapu megoldast keresel.
Viszont ha nagy savszelesseg kell a kommunikalo processek kozt, akkor shared memory-val jobban jarsz (+semaphore, hogy ne ird egyszerre azonos reszeit).
Mind2 Sys V IPC, szoval ha most meg tudod oldani a message queue-t, akkor ezt is.

--
-Tolthetek egy kis teat?
-Tolthetsz, de akkor seedeld is!

Az igazság az, hogy létre kéne hoznom mind MP, mind SHM felületet.

Körülbelül arról van szó, hogy egy könnyen portolható wrappert írok egy adott hardveren már létező programkönyvtárra, mely annak a hardvernek a lehetőségeit alaposan kihasználja, ámde emiatt PC-n nem fut.
Lényegében a user választja ki, hogy a hardver saját libjének rutinjait fogja a könyvtár hívogatni, vagy szabványos rendszerhívásokat.

PVM-mel és openmpi-vel az a bajom, hogy portolni kéne, és ez főleg az openmpi-nél elég macerásnak tűnik, kb. nulla leírást találtam róla, mit is kéne csinálni. Láttam, hogy az OPAL-ban kéne írogatni egy-két rutint, de hogy mit és hogyan, az nem túl világos...
---
WGábor

Az SHM-nek a hatalmas előnye a sebesség és a kényelem (nem kell byte stringgé alakítani az objektumokat).

Másrészt a socketes megoldás előnye, hogy végtelenül kicsiny energiával átalakítható, hogy ne csak gépen belül menjen, hanem hálózaton keresztül több gép között is.

En pthreaddel oldottam meg vegul a szamitasaimat, mert a memoriafoglalas mellette teljesen szokvanyos, nem kell az shm-mel foglalkozni. Es hivni pont ugyanugy kell, mint a fork-ot a szulo processzbol, raadasul van rengeteg fajta semaphorja/mutexe. A halozati kommunikacio persze maradt socketes.