Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (GNU/Linux, *NIX, *BSD und Co) » Auf Prozess warten

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
11.08.2009, 08:46 Uhr
~FreiherrEintritt
Gast


Ich will aus meinem Programm heraus einen Reihe externer Prozesse starten. Jeder Prozess wird dabei aus einem eigenen Thread heraus gestartet.
Allerdings rufe ich nicht direkt eine bestimmte ausführbare Datei auf. Die Start-Kommandos sehen so aus: "ssh name@ip nohup nice -n 19 ..."

Auf welche Art kann ich diesen Aufruf durchführen, dass mein Programm auf das Ende der
Child-Prozesse wartet, also dass der jeweile Thread erst nach Ende des Prozesses endet.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
11.08.2009, 08:54 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hi,

WaitForSingleObject und GetExitCodeProcess ist dein Freund
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
11.08.2009, 09:32 Uhr
~FreiherrEintritt
Gast


Das sind aber Windows-Funktionen, oder?

Es geht mir nicht darum, darauf zu reagieren, dass ein Thread beendet ist, sondern darum, den Thread erst dann zu beenden, wenn das daraus aufgerufene externe Programm beendet ist.


C++:
void* threadProc(void *p) {
    // externen aufruf
    // --> hier soll gewartet werden <--
    ....
}

int main() {
    pthread_create(..., ..., threadProc, ...);
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
11.08.2009, 10:45 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


oh hab grad net gesehen das es unter linux ist *ooops*

da kommts drauf an was du tust:

wie rufst du das externe programm denn auf?

damit deine threads nicht zu zombies werden, solltest du in main mit "pthread_join" auf beendigung des threads warten (pthread_create liefert dir ja ein thread-handle)
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
11.08.2009, 11:08 Uhr
~FreiherrEintritt
Gast



Zitat von FloSoft:

wie rufst du das externe programm denn auf?



Das ist ja genau die Frage
Habs erst mal auf die Schnelle mit system() getesetet, aber das wartet nicht auf Beendigung. Wahrscheinlich weil der String, den ich da übergebe, das externe Programm mit nohup aufruft.
Der Aufruf sieht wie gesagt folgendermaßen aus: "ssh name@ip nohup nice -n 19 programmB &"

Ich bin mir auch nicht sicher, ob das nohup in den Aufrufen von ProgrammB überhaupt notwendig ist. Das Parent-Programm A, dass die Aufrufe macht wird nämlich auch mit nohup aufgerufen und soll die Arbeit auf mehrer Rechner verteilen, indem es ProgrammB verschiedene Bereiche eines Parameterraums ablaufen lässt.

Was ich am Ende haben will ist ein "nohup nice -n 19 ProgrammA [Parameter] &", so dass Programm A und alle Programme B noch weiterlaufen, wenn ich mich auslogge.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
11.08.2009, 14:03 Uhr
okraits



Warum benutzt Du nicht einfach screen?
--
www.okraits.de/

Dieser Post wurde am 11.08.2009 um 14:04 Uhr von okraits editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
11.08.2009, 14:04 Uhr
0xdeadbeef
Gott
(Operator)


Moment, geht's jetzt um Prozesse, oder um Threads?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
11.08.2009, 15:23 Uhr
~FreiherrEintritt
Gast


Anscheind hab ich das ganze etwas unklar formuliert. Ich hab ein Programm A, welches z.B. so aufgerufen wird:
"nohup nice -n 19 ./ProgA min=0 max=100 n=3 &"

Programm A teilt nun das Intervall [min; max] in n Bereiche ein, startet n mal das Programm B und übergibt die jeweiligen Intervallgrenzen. Diese Aufrufe von Programm B sollen aus Perfomance-Gründen auf verschiedene Rechner verteilt werden.

In diesem Fall z.B.
"ssh name@ip1 nohup nice -n 19 ProgB min=0 max=33 &"
"ssh name@ip2 nohup nice -n 19 ProgB min=34 max=66 &"
"ssh name@ip3 nohup nice -n 19 ProgB min=66 max=100 &"

Da Programm A die Ausgabe-Dateien der einzlenen ProgBs zusammensetzen soll, muss ich aus A heraus festellen können, wann alle Bs beendet sind.
Mein erster Ansatz sieht in vereinfachter Form so aus:


C++:
int main() {
    vector<pthread_t> vThreads; vThreads.resize(n);
    vector<tData> threadData; threadData.resize(n);

    unsigned int jobCounter = 0;     // Anzahl der im Gesamten gestarteten Prozesse
    unsigned int jc=0;                   // Anzahl der noch laufenden Prozesse (wird
                                               //   beim Erstellen eines Prozesse erhöht und beim
                                               //   Beenden wieder erniedrigt)

    do {
        if(jobCounter < n) {
            // freie IP holen
            threadData[jobCounter].ip = freieIP;
            threadData[jobCounter].pjc = &jc;
            threadData[jobCounter].........
            ........

            pthread_create(&(vThreads[gjc]), NULL, threadProc, &(threadData[jobCounter]));
            ++jobCounter;
            ++jc;
        }
    } while(jc > 0);     // Schleife dürfte erst abbrechen, NACHDEM alle Threads
                             // beendet wurden, also nachdem alle externen Prozesse
                             // beendet wurden.

}

void* threadProc(void *p) {
    tData *tp = (tData*)p;
    string strCall = "Aufruf von Programm B zusammenbasteln: ssh....";
    system(strCall.c_str());
    // Hier soll gewartet werden, wird aber nicht...
    (*p->jc)--;
    return NULL;    
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
11.08.2009, 15:39 Uhr
FreiherrEintritt



Hier noch mal in lesbarer Form, sorry:


C++:
int main() {
    vector<pthread_t> vThreads; vThreads.resize(n);
    vector<tData> threadData; threadData.resize(n);

    unsigned int jobCounter = 0; // Gesamtzahl der gestarteten Prozesse
    unsigned int jc=0;  // Anzahl der noch laufenden Prozesse
              // (wird beim Erstellen eines Prozesse erhöht und beim
             //   Beenden wieder erniedrigt)

    do {
        if(jobCounter < n) {
            // freie IP holen
            threadData[jobCounter].ip = freieIP;
            threadData[jobCounter].pjc = &jc;
            threadData[jobCounter].........
            ........

            pthread_create(&(vThreads[gjc]), NULL, threadProc, &(threadData[jobCounter]));
            ++jobCounter;
            ++jc;
        }
    } while(jc > 0 || jobCounter < n);
      // Schleife dürfte erst abbrechen, NACHDEM alle Threads
      // beendet wurden, also nachdem alle externen Prozesse
      // beendet wurden.

}

void* threadProc(void *p) {
    tData *tp = (tData*)p;
    string strCall = "Aufruf von Programm B zusammenbasteln: ssh....";
    system(strCall.c_str());
    // Hier soll gewartet werden, wird aber nicht...
    (*p->jc)--;
    return NULL;    
}


Dieser Post wurde am 11.08.2009 um 15:45 Uhr von FreiherrEintritt editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
11.08.2009, 17:25 Uhr
0xdeadbeef
Gott
(Operator)


Ja ne, wenn du den Kram in eine abgekoppelte Sub-Subshell auslagerst, dann wartet dein Prozess nicht darauf, dass er zurückkommt. Eine einfache Möglichkeit wäre, das & am Ende des Kommandos zu entfernen, allerdings wäre es natürlich bedeutend schöner, das ganze mit fork, exec* und wait zu machen.

Im einfachsten Fall könnte das etwa so aussehen:

C++:
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

void do_stuff(int min, int max, int n);

int main(void) {
  size_t n;
  int *mins, *maxs, *ns;
  pid_t pid;

  // Initialisieren der Eingabedaten
  // Insbesondere Speicher für die Arrays

  for(size_t i = 0; i < n; ++i) {
    pid = fork();

    if(pid == 0) {
      do_stuff(mins[i], maxs[i], ns[i]);
      // kehrt nie zurück.
    }
  }

  for(size_t i = 0; i < n; ++i) {
    wait(NULL);
  }

  // Aufräumen

  return 0;
}

void do_stuff(int min, int max, int n) {
  char minarg[50], maxarg[50], narg[50];
  sprintf(minarg, "min=%d", min);
  sprintf(maxarg, "max=%d", max);
  sprintf(  narg,   "n=%d",   n);

  execlp("nohup", "nice", "-n", "19", "./ProgA", minarg, maxarg, narg, NULL);
}



Einfacher wäre aber wohl, das ganze von vorneherein als Shellskript anzulegen.

Nachtrag: Oder du benutzt ein dafür ausgelegtes Framework, wie etwa http://taktuk.gforge.inria.fr/
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 11.08.2009 um 17:31 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (GNU/Linux, *NIX, *BSD und Co) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: