Asynchrones Starten eines unabhaengigen Prozesses aus C++ Programm



  • Grüß Euch,
    ich suche nach einer einfachen Moeglichkeit, aus einem C++ Programm ein anderes Programm asynchron zu starten. D.h. der neue Prozess soll angestossen werden, ohne dass das aufrufende Programm die Beendigung des neuen Prozesses oder eine Erfolgsmeldung über den Start abwartet. Beiden Prozesse brauchen auch keine Kommunikation miteinander.

    Das Ganze soll moeglichst portabel sein, auf jeden Fall unter Win und Linux funktionieren. Gibt es in der STL oder Boost so was ? Ich habe dort vergeblich gesucht ...

    P.S.
    Wenn ich unter Linux das Programm mit

    system("kghostview ~/IT/project/PostScriptSpooler/debug/src/data.ps");
    

    aufrufe, wird solange gewartet, bis das aufgerufen Prog kghostview wieder geschlossen wird 😞 Ausserdem habe ich gehoert, dass system "boese" ist und Probleme bereiten kann.



  • Für Linux geht folgendes

    #include <sys/types.h>
    #include <unistd.h>
    
    int run_application(char const *app, char *const argv[]) {
      pid_t pid = fork();
      if(pid < 0) {
        return -1;
      }
      else if(pid == 0) {
        if(execvp(app, argv) == -1) {
         exit(1);
        }
        exit(0);
      }
      return 0;
    }
    

    oder

    system("kghostview ~/IT/project/PostScriptSpooler/debug/src/data.ps &");
    


  • Danke ! Auf die 2.Loesung haette ich selber kommen koennen, manchmal hat man Brett vor Kopf ... 😉

    Wie sieht es aber bei Windows aus ??



  • Hab ein bisschen gegoogelt, die 1. Loesung scheint die systemunabhaengige sein. Setsam ist, dass ich in meiner C++ Reference nicht die exec* -Befehle und das fork() - Befehl finde. Kann mir jemand eine Online-Quelle nennen, wo ich mich schlau machen kann ??



  • Nein, die ist nicht Systemunabhängig. man: fork(2) und man: execvp(3) sind Funktionen (_nicht_ Befehle) aus POSIX (_nicht_ ISO C++), die unter Windows glaube ich nicht zur Verfügung stehen (gibt POSIX-Layer, so wie Cygwin und Windows NT hatte zumindest auch etwas in die Richtung). Aber es ist nicht unbedingt portabel zwischen Windows und Linux.

    Unter Windows gibt es irgend eine umständliche WinAPI-Funktion dafür.



  • Hmm, danke, aber das hilft mir nicht weiter. Gibt' denn dafuer keine portable Library, die die systemspezifischen Dinge kapselt ???



  • Ich kenne zumindest keine. Aber wenn es nur um die Kleinigkeit geht, kannst du ja mittels eines ifdefs eine Fallunterscheidung machen für Windows und Linux/Unix.



  • Als TCHAR version:

    #include <windows.h>
    
    int run_application(LPCTSTR app, LPTSTR const argv[])
    {
        // Variablen (->C) initalisierung fast immer überflüssig
        size_t len = 0;
        LPTSTR cl = NULL, end = NULL;
        LPTSTR* argv2 = argv;
        BOOL suc = FALSE;
        PROCESS_INFORMATION pi;
        STARTUPINFO si = {0};
    
        // si füllen
        si.cb = sizeof(si);
        // ...
    
        // Länge des cl strings berechnen
        for(len = 0; *argv2 != NULL; argv2++)
            len += _tcslen(*argv2) + 2; // +2, da alle args in "" setzen
                                       // _tcslen wegen TCHAR aber _ -> vendor specific
        // Command line buffer erstellen
        LPTSTR cl = malloc(sizeof(TCHAR) * len);
        cl[0] = 0; // strcat
        // cl füllen
        for(argv2 = argv, end = cl; *argv2 != NULL; argv2++)
        {
            end += _stprintf(end, "\"%s\"", *argv2); // %s ist wie TCHAR %S immer umgekehrt
            _tcscat(cl, *argv2);
        }
        // Prozess erstellen
        suc = CreateProcess(app, cl, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
        return suc ? 0 : -1;
    }
    

    Also ich finde das mitnichten umständlicher 😃 und besser als eine kopie des eigenen prozesses mit einem anderen zu ersetzen ist es allemal. :p



  • nachtrag:
    free(cl);

    und in zeile 22 sizeof(TCHAR) * (len + 1)



  • nachtrag2: zeile 27 "\"%s\"" -> TEXT("\"%s\"")



  • nachtrag3: -zeile 28



  • Danke, der C-Stil ist ist fuer mich etwas ungewoht, ich werde Deine Loesuing ausprobieren und gebe dann Bescheid.


Anmelden zum Antworten