Prozess starten der in Hintergund läuft.



  • Hi,

    nachdem ich nun ca. 2 Stunden googln hintermir habe, war ich so frech mich mal hier zu reggen.

    Es geht um folgendes: Ich möchte aus einem C++ Programm ein Shellscript aufrufen. Das geht soweit mit System. Aber...nun kommt es......ich möchte NICHT warten bis das script fertig ist. Sondern das C++ Programm soll den aufruf machen und sofort weitelaufen. Ich brauche keinerlei info´s von dem Script. Ich möchte es nur Starten, quasi im hintergrund.

    Noch eine kleine anmerkung zu meiner Person. Ich komme eigentlich aus der Assembler-ecke. Folgende vorkenntnisse liegen vor.

    Pascal / TP
    PHP
    Shellscripte
    x86, 6502, 68000.. (Maschinesprache da ich meistens sehr hardwarenah proggen musste)
    usw.

    Aber leider weder C noch C++. Ich hab mich mit C eigentlich nie richtig anfreunden können. Aber nun muss ich in C proggen. Und stosse gleich auf ein für mich unlösbares Problem. Währe echt nett wenn man mir hier helfen könnte. Am besten anhand eines beispiels.

    Vielen dank im Voraus....



  • unter Linux...:

    system("./test &");
    

    würde das prog test im hintergrund laufen lassen...



  • Muss das Skript aus der Anwendung heraus gestartet werden? Ansonsten würde ich den Aufruf der beiden Anwendungen wieder in ein Shellskript zusammenpacken. Ansonsten könntest du system auch in einem Thread mit boost::thread starten (wobei in Unix würde ich eher die von christoferw vorgeschlagene Variante nehmen):

    #include <string>
    #include <cstdlib>
    #include <boost/thread/thread.hpp>
    
    class StartScript {
      std::string file;
    public:
      StartScript(const std::string &_file) : file(_file) {}
      void operator()() {
        system(file.c_str());
      }
    };
    
    int main() {
      StartScript app("./test"); // oder "./test &"
      boost::thread t(app);
      // Rest der Anwendung
      t.join(); // falls Anwendung vor Skript fertig ist, auf das Skript warten
    }
    


  • Unter windows:

    std::system( "start myshellscript.ext" );
    


  • Ui,

    thx erstmal für die antworten. Aber system ist unix. CPU ist kein x86. Mit & hab ich es schon versucht. Das ding wartet bis die bash/sh fertig ist. Ich habe auch schon versucht ein script "vorzustarten" was dann das eigentliche script mit & startet. Wartet leider auch. Busybox ist die Version v1.1.3.

    MfG



  • Stimmt, system wartet bis die Anwendung beendet ist, was damit zusammenhängt das system den Rückgabewert der Anwendung zurückgibt. Die Methode mit dem Thread funktioniert auf jedenfall (eben auch nochmal kurz getestet).



  • Hallo,
    also die Lösung mit Threads + system erscheint mir unnötig kompliziert. Warum nicht einfach eine systemspezifische Funktion wie spawn verwenden? Als Parameter P_NOWAIT übergeben und fertig. spawn ist eine POSIX-Funktion und sollte somit ja unter Unix existieren.



  • Hi,

    nochmal besten dank an die, die mir helfen wollten bzw. es getan haben. Ich mach es nun so wie folgt, und es klappt sogar *freuwiesau*

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #include <sys/types.h> 
    
    void Prog_exec(const char *prg_name)
    {
       signal(SIGCHLD, SIG_IGN);
       switch (fork())
       {
          case -1:
             perror("forkerror");
             break;
          case 0:
             execl ("/bin/sh", "sh", prg_name, NULL);
             perror("execl");
       }
    }
    

    Suchbegriffe: Prozess , hintergrund , backround , aufrufen , kind , child , programm , aufrufen , hintergrundprozess , zombie vermeiden



  • Jo, fork wollte ich vorschlagen, bin damit aber nit so bewandert, da ich nicht wirklich viel unter Unix programmiere. 🙂

    Dieser Thread aber wohl im Unix-Forum besser aufgehoben @HumeSikkins.



  • Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum Linux/Unix verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • also wie gesagt arbeitet fork() folgendermaßen.

    pid_t pid=fork()

    pid ist 0 falls du dich im Kind Prozess befindest
    -1 falls wasch schief ging bei der Prozesserzeugung und >0 falls du nach dem Aufruf im Elternprozess bist.
    Was mir in Verbidnung mit fork anfangs immer Kopfschmerzen bereitete sind zombie Prozesse. Sie entstehen wenn das Kind vor dem Elternprozess beendet wird.
    Am besten fügst du vor dem Aufruf von fork ein signal(SIGCHLD,SGN_IGN) ein damit das Signal der Beendigung vom Kindprozess im Elternprozess ignoriert wird.

    Allerdings frage ich mich bei der Sache warum man hier einen fork braucht.
    Mit execl usw geht das doch auch ohne oder täusche ich mich da?



  • Hi,

    nur mit execl hab ich das nicht hinbekommen. Wie gesagt, ich tue mich im moment noch etwas schwer mit der Syntax.....
    Irgendwie finde ich c/c++ unleserlich....

    MfG



  • #include <stdio.h>
    #include <unistd.h>
    
    char *argv[4],*env[2];
    argv[0]="/bin/ls";
    argv[1]="--color";
    argv[2]="/home";
    argv[3]="NULL";
    env[0]="LS_COLORS=fi=00:di=01";
    env[1]=NULL;
    execve("/bin/ls", argv, env);
    perror("execve() failed");
    

    oder

    execlp("ls","ls","-F","/home",NULL);
    

    Das Beispiel stammt aus dem Buch C und Linux von Martin Gräfe
    und ich find es ist kein so großer Schinken und enthält viele nützliche Dinge...
    🙂



  • Hi,

    mit "meiner" routine gibt es ein dickes problem. Wenn das shell-script zuende ist, bleibt es als Zombie im system. Wenn ich dann dem Parent kille, dann verschwinden auch die ganzen Zombies. Hat da vielleicht einer ne idee???

    So sieht es aus. 59 processes: 51 sleeping, 2 running, 6 zombie, 0 stopped

    MfG

    PS.:root 6701 0.7 0.0 0 0 pts/0 Z 17:11 0:00 [sh <defunct>]



  • du musst für jedes fork, nachdem der Prozess zu Ende ist, irgend wann ein man: wait(2) aufrufen. Sonst bleibt der "Zombie" übrig.



  • Thx,

    aber mit wait(2); bekomme ich einen compilererror und wait(0); wartet bis der prozess fertig ist. Nun weiss ich nichtmehr weiter.

    Hier mal die Fehlermeldung: error: incompatible type for argument 1 of `wait'

    MfG und Thx



  • |JayDee| schrieb:

    aber mit wait(2); bekomme ich einen compilererror und wait(0); wartet bis der prozess fertig ist. Nun weiss ich nichtmehr weiter.

    Klick das man: wait(2) mal an. Der Zweier heißt nur, dass Du in Sektion 2 Deiner Manpages Hilfe findest, nicht dass Du ihn als Argument übergeben sollst.



  • Ne kein wait, einfach
    vor dem fork
    signal(SIGCHLD, SIG_IGN);
    dann geht das



  • Puhh,

    das mit signal(SIGCHLD, SIG_IGN); klappt prima. Ich danke dir 1000mal. Ich werde mein prog hier im board dementsprechend abändern. Vieleicht braucht das mal einer.

    Gruss und nochmal fett Thx......



  • Ich hab da ewig recherchiert für...
    Ich wollte dir nur ne Menge arbeit ersparen.
    Vor allem weil man immer was zu wait findet obwohl man das in 99% der Fälle niemals braucht. man will ja nicht parralele Prozesse synchronisieren.


Anmelden zum Antworten