2011-06-24 16 views
11

En el siguiente código creo un número de hilos, y cada uno de los hilos duerme durante algunos segundos.hacer que el programa principal espere a que terminen los hilos

Sin embargo, mi programa principal no espera a que terminen los subprocesos, supongo que los subprocesos continuarán ejecutándose hasta que terminen solos.

¿Hay alguna manera de hacer que los subprocesos continúen ejecutándose aunque termine el subproceso que realiza la llamada?

#include <pthread.h> 
#include <iostream> 
#include <cstdio> 
#include <cstdlib> 


int sample(int min,int max){ 
    int r=rand(); 
    return (r %max+min); 
} 



void *worker(void *p){ 
    long i = (long) p; 
    int s = sample(1,10); 
    fprintf(stdout,"\tid:%ld will sleep: %d \n",i,s); 
    sleep(s); 
    fprintf(stdout,"\tid:%ld done sleeping \n",i,s); 
} 

pthread_t thread1; 

int main(){ 
    int nThreads = sample(1,10); 

    for(int i=0;i<nThreads;i++){ 
    fprintf(stderr,"\t-> Creating: %d of %d\n",i,nThreads); 
    int iret1 = pthread_create(&thread1, NULL, worker, (void*) i); 
    pthread_detach(thread1); 
    } 
    // sleep(10);//work if this is not commented out. 
    return 0; 
} 

Gracias

Editar:

Lo siento por no aclarar, ¿es posible sin mantener explícitamente la cuenta de mis hilos de funcionamiento actuales y mediante el uso de unirse.

+0

Si esto fuera una interfaz de usuario gráfica, sí, esto sería cierto porque hay una ciclo de mensajes. Debes tener una condición para continuar corriendo hasta que todos los hilos hayan terminado, como unirse. –

Respuesta

3

Cada programa tiene un hilo principal. Es el hilo en el que se ejecuta la función main(). Cuando finaliza la ejecución de ese hilo, el programa finaliza junto con todos sus hilos. Si desea que su subproceso principal espere otros subprocesos, use debe usar la función pthread_join

+0

Cuando finaliza la ejecución del hilo principal, al menos en Linux, el programa/proceso no finaliza, sino que se ejecuta como un zombi hasta que los otros hilos terminen y luego el programa/proceso finaliza también. Para comprobar esto, codifique un hilo que duerme durante N segundos, luego, desde el hilo principal, cree el hilo y emita pthread_exit (0) desde el hilo principal y observe el proceso con vida, pero en estado zombie y luego de N segundos termina el hilo. que hace que el programa/proceso termine también. – user1656730

2

Debe realizar un seguimiento de los subprocesos. No está haciendo eso porque está usando la misma variable thread1 en cada hilo que está creando.

Realiza un seguimiento de los hilos creando una lista (o matriz) de tipos pthread_t que pasa a la función pthread_create(). Entonces usted pthread_join() esos hilos en la lista.

edición:

Bueno, es muy vago de que no llevar la cuenta de hilos en ejecución. Sin embargo, puede lograr lo que desea teniendo una var global (protegida por un mutex) que se incrementa justo antes de que termine un hilo. Luego en su hilo principal puede verificar si esa var obtiene el valor que desea. Diga nThreads en su código de muestra.

+0

Si utiliza la segunda solución, no olvide que todos los accesos a la variable deben estar sincronizados. –

2

que necesita para unirse cada hilo se crea:

int main() 
{ 
    int     nThreads = sample(1,10); 
    std::vector<pthread_t> threads(nThreads); 

    for(i=0; i<nThreads; i++) 
    { 
      pthread_create(&threads[i], NULL, worker, (void*) i) 
    } 

    /* Wait on the other threads */ 
    for(i=0; i<nThreads; i++) 
    { 
      status* status; 
      pthread_join(threads[i], &status); 
    } 
} 
1

usted aprendió su suposición era errónea. Main es especial. Salir de main matará tus hilos. Así que hay dos opciones:

  1. Uso pthread_exit de salida principal. Esta función le permitirá salir de main pero mantener otros hilos en ejecución.

  2. Haz algo para mantener la vida activa. Esto puede ser cualquier cosa desde un bucle (estúpido e ineficiente) a cualquier llamada de bloqueo. pthread_join es común, ya que bloqueará pero también le dará el estado de devolución de los hilos, si le interesa, y limpiará los recursos del hilo muerto. Pero a los efectos de evitar que principal termine cualquier llamada de bloqueo, p. Ej. seleccionar, leer un tubo, bloque en un semáforo, etc.

Desde Martin mostró join(), aquí está pthread_exit():

int main(){ 
    int nThreads = sample(1,10); 

    for(int i=0;i<nThreads;i++){ 
    fprintf(stderr,"\t-> Creating: %d of %d\n",i,nThreads); 
    int iret1 = pthread_create(&thread1, NULL, worker, (void*) i); 
    pthread_detach(thread1); 
    } 

    pthread_exit(NULL); 
} 
Cuestiones relacionadas