Fórum Ubuntu CZ/SK

Ubuntu pro osobní počítače => Software => Příkazový řádek a programování pro GNU/Linux => Téma založeno: ondrejandrej 15 Prosince 2010, 11:35:03

Název: Spuštění externí aplikace z C++ programu a její ukončení [vyřešeno]
Přispěvatel: ondrejandrej 15 Prosince 2010, 11:35:03
Ahoj,

potřebuji spouštět periodicky externí aplikaci z mého programu psaného v C++ a po nějaké době ji ukončit odesláním Ctrl-C. Zřejmě to nepude s funkcí system() z stdlib.h, protože volání této funkce můj program zastaví a program bude pokračovat až když externí aplikace sama skončí.

Máte nějaký nápad?
Název: Re: Spuštění externí aplikace z C++ programu a její ukončení odesláním Ctrl-C
Přispěvatel: Martin - ViPEr*CZ* 15 Prosince 2010, 12:08:32
Zatím nechápu příliš takovou potřebu... ale napadlo mě třeba řešení:

- přes thread vlákno spustit tu danou aplikaci klidně přes system()
- pak přes jiné vlákno v určitý čas zavolat kill na tu danou aplikaci, která pak skončí

Bohužel neznáme přesnější specifikaci problému.

PS: měli by existovat (nevím teď z hlavy) nějaké exec metody kterým nezáleží kdy daná app skončí či jakým způsobem skončí... takže by daný thread nezablokovalo volání system(), které by si stále myslelo, že daná aplikace běží, i když by ji kill zrušil v jiném vláknu... říkám z hlavy neznám teorii... je to jen nástřel logiky  ;)
Název: Re: Spuštění externí aplikace z C++ programu a její ukončení odesláním Ctrl-C
Přispěvatel: ondrejandrej 15 Prosince 2010, 12:16:59

Díky, napadlo to i mně, ale zdá se, že lepší řešení je knihovna PStreams (http://pstreams.sourceforge.net/), která je založená na popen(). Jdu to s tím zkusit.
Název: Re: Spuštění externí aplikace z C++ programu a její ukončení odesláním Ctrl-C
Přispěvatel: mk33 15 Prosince 2010, 13:27:51
Co takhle: vytvořit nový proces v něm spustit Váš program a předat mu terminál?
int tcsetpgrp(int fildes, pid_t pgid);
Název: Re: Spuštění externí aplikace z C++ programu a její ukončení odesláním Ctrl-C
Přispěvatel: ondrejandrej 15 Prosince 2010, 14:40:37

Zatím se mi nepovedlo to rozběhat s popen(). Mezitím vám můžu objasnit, k čemu to potřebuji. Potřebuji v definovaném čase spustit pidgin, určitou dobu ho nechat spuštěn a potom ho ukončiť. Je to z toho důvodu, aby mě další uživatelé viděli jako přihlášeného v čase, který si určím.
Název: Re: Spuštění externí aplikace z C++ programu a její ukončení odesláním Ctrl-C
Přispěvatel: ondrejandrej 15 Prosince 2010, 15:01:10
takze lepsi a daleko verzatilnejsi je zabudovat si do sveho programu nejake jednoduche scripting API
- to jsem nepochopil.

Zatím mám tenhle program:
Kód: [Vybrat]
#include <iostream>
#include <stdio.h>

using namespace std;

int main(int argc, char **argv) {
    FILE * pidgin_inst;
    char retaz[10];
   
    retaz[0] = 'q';
    retaz[1] = '\0';
   
    pidgin_inst = popen("mplayer zvuky.mp3", "w");
   
    sleep(3);
   
    cout << "Ted poslu 'q'.\n";
    fprintf(pidgin_inst, "%s", retaz);
 
    sleep(3);
       
    cout << "Ted bude volání pclose()\n";
    pclose(pidgin_inst);
 
    return 0;
}
Chová se to takhle: je spuštěn mplayer, začne se přehrávat mp3. Po tří sekundách se vypíše "Ted poslu 'q'.", ale mplayer neskončí. Po šesti sekundách mplayer skončí (na volání pclose).

Otázka: proč neskončí na poslání q? Vždyť klávesou q se normálně ukončuje mplayer.
Název: Re: Spuštění externí aplikace z C++ programu a její ukončení odesláním Ctrl-C
Přispěvatel: premet 15 Prosince 2010, 15:16:39
Podle mě to tímhle způsobem fungovat nebude, spíš bych na to šel bud v nějakým skriptovacím jazyce, klidně by se dalo něco sbastlit v Bashi nebo bych použil třeba vytvoření nového procesu přes fork() a pak jen nějakou funkci na ohlídání toho času a poslal pak signál k ukončení tomu procesu podle jeho PID.

Ale místo funkce system() bych použil nějakou z funkcí exec(), protože system() blokuje některé signály.
Název: Re: Spuštění externí aplikace z C++ programu a její ukončení odesláním Ctrl-C
Přispěvatel: ondrejandrej 15 Prosince 2010, 15:19:49

No tak dobře, klidně ve skriptovacím jazyce. Ale jak můžu ze skriptu ukončit aplikaci, která se neukončuje sama?
Název: Re: Spuštění externí aplikace z C++ programu a její ukončení odesláním Ctrl-C
Přispěvatel: pacholik 15 Prosince 2010, 15:31:50
> jak můžu ze skriptu ukončit aplikaci, která se neukončuje sama?

Kód: [Vybrat]
killall --signal SIGINT pidginhttp://www.abclinuxu.cz/clanky/unixove-nastroje-13-ps-kill-a-signaly
Název: Re: Spuštění externí aplikace z C++ programu a její ukončení odesláním Ctrl-C
Přispěvatel: Martin - ViPEr*CZ* 15 Prosince 2010, 15:32:49

No tak dobře, klidně ve skriptovacím jazyce. Ale jak můžu ze skriptu ukončit aplikaci, která se neukončuje sama?
Určitě přes kill... i když nevidím důvod si stáhnout source pidginu a naprogramovat ho, že poběží přesně určený čas třeba podle parametru spuštění. Pak už ho jen přes cron v ten daný okamžik nechat spustit s oním parametrem a program se přesně v daný okamžik zapne... a poběží tak dlouho jaké bude číslo v parametru nějakém ;-)

PS: pacholik byl s killem rychlejší  ;D
Název: Re: Spuštění externí aplikace z C++ programu a její ukončení odesláním Ctrl-C
Přispěvatel: premet 15 Prosince 2010, 15:34:30
Kód: [Vybrat]
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

int main()
{
    
     pid_t new_process;
    
     new_process = fork();

     if (!new_process) {

execl("/usr/bin/vlc", "vlc",(char *) 0);


     }
    
     sleep(3);
    
     kill(new_process,9);
    
     return 0;
    
}
Název: Re: Spuštění externí aplikace z C++ programu a její ukončení odesláním Ctrl-C
Přispěvatel: ondrejandrej 15 Prosince 2010, 15:58:00

Ten příkaz s killall funguje, děkuji všem za pomoc. Ten céčkový kód možná taky někdy využiju.