2010-09-05 7 views
8

Tengo un hilo principal que genera alrededor de 20 hilos de trabajo.
Necesito detener el hilo Principal hasta que todos los demás hilos hayan terminado.
Sé (thread) .Join. Pero eso solo funciona para un hilo.¿Cómo esperaría a que se detengan varios subprocesos?

y Multiple Combina un rendimiento herido como este.

t1.Join()
t2.Join()
...
t20.Join()

como el programa espera una por una para cada parar.

¿Cómo haré que el hilo principal espere a que termine todo un conjunto de hilos?

+5

Este comportamiento se desea, ¿verdad? Realmente no importa que espere t1 primero (mientras que t3 ya está listo), al final, cuando callstackpointer pasa por 't20.Join;' usted sabe que todos los hilos están detenidos. – Excel20

+0

Vea también http://stackoverflow.com/questions/263116/c-waiting-for-all-threads-to-complete –

+0

El tratamiento de hilos como los dulces es un error común. Solo inicie 20 hilos cuando tenga una máquina con al menos 20 núcleos de CPU. Comenzar más en realidad ralentiza su programa. Obtener el bloqueo correcto para tantos subprocesos también es * muy * difícil, normalmente solo se obtienen hilos esperando el uno al otro. –

Respuesta

11

realmente debería mirar en Task Parallelism (Task Parallel Library). Utiliza un grupo de subprocesos, pero también administra el robo de tareas, etc.

Cita: "El TPL escala el grado de concurrencia de forma dinámica para utilizar de manera más eficiente todos los procesadores disponibles. Además, el TPL maneja las particiones . de la obra, la programación de las discusiones sobre la ThreadPool, el apoyo cancelación, la administración del estado, y otros detalles de bajo nivel "en Task Parallel Library

se puede utilizar la siguiente manera:

Task[] tasks = new Task[3] 
{ 
    Task.Factory.StartNew(() => MethodA()), 
    Task.Factory.StartNew(() => MethodB()), 
    Task.Factory.StartNew(() => MethodC()) 
}; 

//Block until all tasks complete. 
Task.WaitAll(tasks); 

O si lo utiliza algún tipo de ciclo para generar tus hilos:

Data Parallelism (Task Parallel Library)

+0

gracias, esto es exactamente lo que estaba buscando. ¿Conoces algún tutorial para la Biblioteca? – akshaykarthik

+0

Este sitio web; http://www.albahari.com/threading/part4.aspx tiene información sobre las últimas características de subprocesamiento de C# 4.0 –

+0

@AKRamkumar Cool :) Hhm, no es algo en particular:/supongo que Google puede encontrar algo decente o de lo contrario busque un buen libro .Net Framework 4.0 o C# 4.0. Tal vez este artículo: http://msdn.microsoft.com/en-us/magazine/cc163340.aspx –

4

Las join están bien si eso es lo que quieres que haga. El hilo principal aún tiene que esperar a que finalicen todos los subprocesos de trabajo. Consulte este sitio web, que es un capítulo de muestra del C# in a Nutshell. Resulta que es el capítulo de enhebrado: http://www.albahari.com/threading/part4.aspx.

1

Si está seguro de que siempre tendrá < 64 subprocesos, puede hacer que cada nuevo subproceso establezca un Suceso antes de que salga, y Espere todos los eventos en su subproceso principal, una vez que todos los subprocesos se inician. El objeto Evento se crearía en el hilo principal y se pasaría al hilo secundario relevante de una manera segura para la ejecución de subprocesos en el momento de creación de subprocesos.

En el código nativo, podría hacer lo mismo en los manejadores de subprocesos, pero no está seguro de cómo hacerlo en .Net.

Ver también esta pregunta previa: C#: Waiting for all threads to complete

2

no puede ver una penalización de rendimiento obvia para esperar a que los hilos para terminar uno por uno. Así, un simple foreach hace lo que quiere sin ningún tipo de campanas unnecerrasy y silbatos:

foreach (Thread t in threads) t.Join(); 

Nota: Por supuesto, hay una función de la API Win32 que permite a la espera de varios objetos (hilos, en este caso) a la vez - WaitForMultipleObjectsEx . Hay muchas clases de ayuda o marcos de enhebrado en Internet que lo utilizan para lo que desea. ¿Pero realmente los necesitas para un caso simple?

2

y varias Uniones dañan el rendimiento de esta manera.

No hay "daño en el rendimiento", si desea esperar a que salgan todos sus hilos, llame a .join() en los hilos.

Stuff sus hilos en una lista y hacer

foreach(var t in myThread) 
    t.join(); 
Cuestiones relacionadas