Spuštění jiného programu z C

Re: Spuštění jiného programu z C
« Odpověď #15 kdy: 21. 04. 2011, 08:22:30 »
Ty programy jsou moje práce - zdrojáky mám.
Jedná se o to, že ta výkonná část musí být samotnej spustitelnej program, protože se musí dát spustit třeba cronem,.. To gui je jen klikátko, kde si člověk může nastavit, co se bude dít a program spustit rovnou.

Neprogramuji moc dlouho, tak mívám někdy problémy. Díval jsem se na ten fork, podle toho co jsem četl, zduplikuje aktuální proces, což podle toho, co si myslím vytvoří identickou kopii procesu, který zabere stejné místo v paměti jako původní, sice jen na chvíli, než to zruším execvem, ale příjde mi to jako plýtvání systémovými zdroji. Pokud se pletu, opravte mě.


Re: Spuštění jiného programu z C
« Odpověď #16 kdy: 21. 04. 2011, 09:20:58 »
Fork nevytvari kopii, ale proces nasdili a kopie vznika az za behu, tak jak se meni obsah pameti v kazdem z obou procesu, rika se tomu copy on write a je to jedna ze zakladnich sluzeb strankovani za podpory procesoru. I tak je pravdou, ze se tam nejakymi prostredky plytva zbytecne, ale neni to tak hrozny, jak to na prvni pohled vypada. Proto vznikl vfork (virtual fork), ten funguje podobne ale u neho se predpoklada, ze vzdycky skonci execem. Vznikly child zastavi parenta, docasne prevezme vsechny prostredky parenta aby mohl provest treba nastaveni rour, signalu, zavreni ci otevreni deskriptoru, no a po zavolani exec se parent ze uvolni s tim, ze pokracuje tam kde prestal. vfork je rychlejsi, ale neni to skutecny fork, jen takovy fake.

Mimochodem, Windows nema tento mechanismus a ruzne akce provadene mezi (v)forkem a execem se tam musi resit jinak, treba sdilenim handlu (descriptoru) a s tim spojene problemy typu "kdo nese zodpovednost za uzavreni handlu". Paradoxne ve Windows se kvuli procesu vyplati poustet vlakno, ktery proces sleduje a po jeho skonceni uzavre vsechna sdilena handle. Atd.

Logik

  • *****
  • 1 031
    • Zobrazit profil
    • E-mail
Re: Spuštění jiného programu z C
« Odpověď #17 kdy: 21. 04. 2011, 09:40:07 »
biggles: no vždyť ta výkonná část může taky používat tu samou knihovnu, ne? Prostě udělej jednoduchou knihovnu a k ní dva fronendy pro cli a gui.

jinak to, co vfork kopíruje je tabulka stránek, u kterejch nastaví příznaky copy on write. Nic moc hroznýho to neni, používalo se to běžně u různejch multiprocesovejch serverů. Ale pokud je k dispozici vfork, není důvod ho nepoužít (pokud teda půjdeš tímto směrem).

ondra: jo, jo - linuxovej přístup vypadá na první pohled "hrozně nebezpečně", ale programuje se daleko líp. Windowsí create process je "allinone" bast.

Re: Spuštění jiného programu z C
« Odpověď #18 kdy: 21. 04. 2011, 11:46:46 »
ondra: jo, jo - linuxovej přístup vypadá na první pohled "hrozně nebezpečně", ale programuje se daleko líp. Windowsí create process je "allinone" bast.

On Microsoft nikdy nechtěl moc forkovat, Windowsy to dodnes neumí, větší tíha byla na vlákna. Možná se tím zase nějaké věci zjednodušují :-)

Logik

  • *****
  • 1 031
    • Zobrazit profil
    • E-mail
Re: Spuštění jiného programu z C
« Odpověď #19 kdy: 21. 04. 2011, 14:30:57 »
Jo, linux zas poměrně dlouho preferoval procesy oproti vláknům, to je fakt - a taky bych řek že vlákna jsou ve výsledku použitelnější (i když teď se zas vývojáři často vracej k samostatným procesům z důvodu bezpečnosti).

Rozdil ale je, že do linuxu se ty vlákna nakonec dostali a časem je i vyladili do rozumný výkonnosti. Zatimco create process je furt stejnej.


Re: Spuštění jiného programu z C
« Odpověď #20 kdy: 21. 04. 2011, 16:16:06 »
Holt si microsoft mysli, ze jen jeho zpusob je jediny spravny. Ono se to pozna snadno podle toho, kdo od koho kopiruje. Linux se postupne naucil vlakna, zatimco Windowse nikdo nenaucil forkovat (PS: cygwin to nejak emuluje, a ve WIndows 7 existuje nejake linuxove api, ktere to snad zvladne)

Jinak CreateProcess je userspacova zalezitost, kde je par kernel volani typu "zaloz prazdny proces", "Namapuj pamet noveho procesu do aktualniho" po kterem nasleduje natazeni image do pameti, relokace, natazeni DLL knihoven a konci to zase kernelovskym vytvorenim vlakna v procesu. Jenze jsem nevidel funkcni API kde by se daly tyto kroky volat separatne. Navic se to od verze meni

Logik

  • *****
  • 1 031
    • Zobrazit profil
    • E-mail
Re: Spuštění jiného programu z C
« Odpověď #21 kdy: 21. 04. 2011, 17:27:49 »
No, ono POSIX api bylo (volitelně) už v NT tuším 3.51 (nebo 4, teď nevím) - jenže když se MS cejtil dost silnej v kramflecích, tak ho zas vyřadil. Takže nějak to we winech jít musí, jen to nebude dokumentovaný.

Ale to co píšeš bych bezezbytku podepsal.

Re: Spuštění jiného programu z C
« Odpověď #22 kdy: 22. 04. 2011, 15:57:21 »
No zrovna teď řeším podobný task. Moje knihovna je založená na posílání různých notifikací při nastalé události. Umím podchytit události typu odemčení semaforu, otevření gate, uvolnění zámku, vykonání operace v jiném vláknu, dokonce i příchod dat na otevření socket. Zatoužil jsem po podobném rozhraní u ukončování procesů. Je tu několik zádrhelů.

Proces spustím normálně vfork + execve ovšem v libovolném vlákně, kde to potřebuji. V tom samém vlákně mohu udělat maximálně waitpid (na rozhraní vyvedeno jako join(), aby to bylo podobné jako u threadů). Thready umí mimojiné při ukončení obeslat listenery a na nich zavolat metodu wakeUp. U Procesu to bude horší, nicméně napadlo mě na to vyčlenit vlákno. Nechce se mi ale vyčlenit vlákno per process, ani se mi nechce vytvářet vlákno v případě, že to není potřeba (volající nebude registrovat listenery). Napadlo mě to udělat tak, jak to mám u soketů, že si soket zaregistruju na globální kolektor, který spustí vlákno a ve vlákně provádí select. Jenže u procesů to není tak jednoduché. Jednak mě docela děsí to, že nemohu selektivně čekat na děti. Mohu čekat jen na všechny, nebo na jedno. Další problém je, že na děti budu čekat v jiném vlákně, než vznikly. A třetí zádrhel je, co udělá linux, když čekatelů na děti bude náhodou víc, třeba když jeden bude čekat na všechny děti a druhý bude čekat jen na jedno selektivně.

Sten

Re: Spuštění jiného programu z C
« Odpověď #23 kdy: 22. 04. 2011, 16:34:18 »
Na takové věci doporučuji eventfd. Je to asi nejlepší řešení, jak vytvořit něco, na co se dá snadno čekat (selectem). Potom stačí v signal handleru SIGCHLD do příslušného eventfd zapsat.

Michal

Re: Spuštění jiného programu z C
« Odpověď #24 kdy: 23. 04. 2011, 09:49:36 »
Osobně bych zkusil doporučení z příspěvku výše:
* dynamickou knihovnu s výkonným kódem
* separátní EXE pro jednotlivá prostředí volající tuto knihovnu

Pokud je problém se zdroji, je vždy možné zkusit něco sdílet. Za to zaplatíš řízením přístupu, ale celkově to není hrozné.

Osobně se mi zdá, že tohle je mnohem jednodušší způsob než roury nebo meziprocesová komunikace...

Hodně štěstí
M.

Re: Spuštění jiného programu z C
« Odpověď #25 kdy: 23. 04. 2011, 20:06:00 »
Taková kaciířská myšlenka. Lze v handleru SIGCHLD zavolat waitpid z WNOHANG? To abych se rovnou dozvěděl, které dítě umřelo.