sistema que pthread programacion procesos proceso pid_t operativo multihilo matrices hilos hijo getpid ejemplo con arbol c++ linux gcc parallel-processing

c++ - pthread - ¿Cómo esperar hasta que se completen todos los procesos secundarios llamados por fork()?



programacion multihilo en c (5)

Estoy horcando una serie de procesos y quiero medir cuánto tiempo lleva completar toda la tarea, es decir, cuando se completan todos los procesos bifurcados. Indique cómo hacer que el proceso principal espere hasta que finalicen todos los procesos secundarios. Quiero asegurarme de detener el cronómetro en el momento correcto.

Aquí está como un código que uso:

#include <iostream> #include <string> #include <fstream> #include <sys/time.h> #include <sys/wait.h> using namespace std; struct timeval first, second, lapsed; struct timezone tzp; int main(int argc, char* argv[])// query, file, num. of processes. { int pCount = 5; // process count gettimeofday (&first, &tzp); //start time pid_t* pID = new pid_t[pCount]; for(int indexOfProcess=0; indexOfProcess<pCount; indexOfProcess++) { pID[indexOfProcess]= fork(); if (pID[indexOfProcess] == 0) // child { // code only executed by child process // magic here // The End exit(0); } else if (pID[indexOfProcess] < 0) // failed to fork { cerr << "Failed to fork" << endl; exit(1); } else // parent { // if(indexOfProcess==pCount-1) and a loop with waitpid?? gettimeofday (&second, &tzp); //stop time if (first.tv_usec > second.tv_usec) { second.tv_usec += 1000000; second.tv_sec--; } lapsed.tv_usec = second.tv_usec - first.tv_usec; lapsed.tv_sec = second.tv_sec - first.tv_sec; cout << "Job performed in " <<lapsed.tv_sec << " sec and " << lapsed.tv_usec << " usec"<< endl << endl; } }//for }//main



Espera de llamada (o waitpid) en un bucle hasta que se tengan en cuenta todos los niños.

En este caso, todos los procesos se sincronizan de todos modos, pero en general se prefiere esperar cuando se puede realizar más trabajo (por ejemplo, grupo de procesos de trabajo), ya que volverá cuando cambie el primer estado del proceso disponible.


Movería todo después de la línea "else // parent" hacia abajo, fuera del ciclo for. Después del bucle de las horquillas, haga otro ciclo for con waitpid, luego detenga el reloj y haga el resto:

for (int i = 0; i < pidCount; ++i) { int status; while (-1 == waitpid(pids[i], &status, 0)); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { cerr << "Process " << i << " (pid " << pids[i] << ") failed" << endl; exit(1); } } gettimeofday (&second, &tzp); //stop time

Supuse que si el proceso hijo no puede salir normalmente con un estado de 0, entonces no completó su trabajo y, por lo tanto, la prueba no pudo generar datos de temporización válidos. Obviamente, si se supone que los procesos secundarios deben ser eliminados por señales, o salir de estados de retorno que no sean 0, entonces deberá cambiar la verificación de errores en consecuencia.

Una alternativa usando espera:

while (true) { int status; pid_t done = wait(&status); if (done == -1) { if (errno == ECHILD) break; // no more child processes } else { if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { cerr << "pid " << done << " failed" << endl; exit(1); } } }

Este no te dice qué proceso en secuencia falló, pero si te importa, entonces puedes agregar código para buscarlo en la matriz pids y recuperar el índice.


for (int i = 0; i < pidCount; i++) { while (waitpid(pids[i], NULL, 0) > 0); }

No esperará en el orden correcto, pero se detendrá poco después de que muera el último niño.


El método más simple es hacer

while(wait() > 0) { /* no-op */ ; }

Esto no funcionará si wait() falla por algún motivo que no sea el hecho de que no quedan niños. Entonces con alguna comprobación de errores, esto se convierte

int status; [...] do { status = wait(); if(status == -1 && errno != ECHILD) { perror("Error during wait()"); abort(); } } while (status > 0);

Ver también la wait(2) página del manual wait(2) .