2012-02-27 14 views
9

será una gran diferencia entre esta dos scenarious:Multithreading versus Multi-Instancing - ¿Qué elegir?

  1. una instancia de aplicación crea 100 hilos para procesar algunos trabajos
  2. 10 instancias de la misma aplicación crea 10 hilos cada uno para procesar trabajos (total de 100)

El número de subprocesos en ambos casos será el mismo. ¿Es algún rendimiento o algún tipo de mejoras de uno sobre otro?

Instancia - es para la aplicación de consola de ejemplo, por lo que en el segundo caso es se ejecutará la aplicación de consola 10. cada una de las aplicaciones tiene su propia carpeta .

+3

3. No cree 100 hilos simultáneamente activos a menos que esté en una Cray con un montón de procesadores. –

+0

¿Sus procesos necesitan comunicarse? – Jimmy

+0

Apolagize para la respuesta incorrecta (que se elimina). Probé el escenario anterior y encontré que la única aplicación de múltiples hilos del proceso es en realidad más rápida que la aplicación de procesos múltiples. Trataré de comprender la razón. – Jimmy

Respuesta

4

Un hilo utiliza menos recursos que un proceso, por lo que teóricamente la opción 1 sería "mejor". Sin embargo, probablemente no notarás mucha diferencia entre los dos, porque 100 procesos de hilos o se ejecutan todos simultáneamente y luchar por los mismos recursos de O/S es casi seguro que hará que tu sistema se detenga.

Elegiría la opción 3: un proceso que contiene un grupo de subprocesos bastante pequeño. De esta forma, algunos trabajos se ejecutarán simultáneamente y el resto hará cola y esperará su turno. Este enfoque también se adapta bien si se va a ejecutar una gran cantidad de trabajos.

Véase el ThreadPool clase, o preferiblemente, una de las muchas abstracciones de nivel superior en la parte superior de la misma (por ejemplo, la task library, o incluso el viejo y simple asynchronous delegates).

0

Una pregunta tan extraña, difícil de encontrar una aplicación práctica ... Pero me imagino que la opción 1 sería mejor desde el punto de vista del rendimiento. Con la ejecución de 10 instancias de la misma aplicación, parecerá que se hará más trabajo. (limpieza, registro, consola abierta, etc.)

Editar * Porque con la opción 1, puede subir el trabajo y dejar que el threadque maneje la carga.

2

Opción 2 tiene (al menos) los siguientes gastos generales:

  • Más objetos de proceso
  • más por proceso de la memoria estática
  • más instancias de la CLR y el código compilados JIT
  • Los cambios de contexto necesita cambiar el espacio de direcciones (muy caro)
  • Menos oportunidades de compartir estructuras de datos de aplicación
  • Necesita cr comunicación oss-process. llamadas a métodos simples se convierten en operaciones IPC
  • más trabajo para usted
  • Más oportunidades para los insectos (IPC comunicación, bombas elevadoras, ...)
  • Peor debuggability
  • Sin integrado de equilibrio de carga a través de la thread- grupo
  • Sincronización más difícil y propensa a errores. Menos elementos incorporados y más lento

¿Por qué elegiría (2) si puede elegir (1)? Hay razones válidas, pero ésas son bastante especiales:

  • Debe tolerar la corrupción arbitraria de la memoria. Esto no es normal en el caso (¡en absoluto!)
  • Necesita la habilidad de matar hilos. Esto no puede hacerse de manera confiable dentro del CLR para hilos individuales. Pero podría hacerlo cooperativamente, que generalmente es la mejor opción, de todos modos
  • Sus hilos deben ejecutarse bajo diferentes usuarios y tal. Esto casi nunca sucede.

En general, cuantos menos procesos, mejor.

+0

Agregué muchas cosas a través de ediciones. – usr

1

Sí, será una gran diferencia. Existen ventajas y desventajas en cada enfoque:

  • Consumo de memoria. Obviamente, cada uno de los 10 procesos requerirá creación de su propio espacio de direcciones, etc.
  • Simplicidad de comunicación/sincronización. Si bien es relativamente fácil comunicar/sincronizar hilos (puede usar secciones críticas, que es una de las maneras más eficientes), será más difícil hacer entre los procesos . En su escenario con 10 procesos y 10 subprocesos, tiene que hacer las dos cosas.
  • Bloqueos. Si uno de los subprocesos en proceso hace que esté mal, todo el proceso fallece.

Yo personalmente preferiría un proceso/muchos hilos. Sin embargo, realmente depende de la tarea.

+0

¿Dijo el OP que sus procesos necesitan comunicarse? – Jimmy

+0

Probé el escenario real y encontré que los procesos múltiples son más lentos. Tienes razón. Borré mi respuesta incorrecta – Jimmy

2

Depende de lo que esté haciendo, pero en la mayoría de los casos la Opción 1 tendrá el mejor rendimiento y será la más fácil de usar.
para darle una respuesta más completa que tendría que saber lo siguiente:

  • Son los 100 Hilos todos realizan la misma tarea?
  • ¿Los 100 subprocesos tienen acceso a los mismos datos?
  • ¿Las tareas manejadas por los hilos tienen un tiempo de inactividad natural (esperando a que termine otro proceso o que un recurso esté disponible)?
  • ¿Las tareas manejadas por los hilos van a todas intentan acceder a un recurso limitado (como el disco duro o la tarjeta de red)?
  • ¿Cuántos hilos simultáneos puede manejar su computadora a la vez (por ejemplo, un procesador de 4 núcleos con Hyper-Threading podría manejar 8 hilos, un procesador de 4 núcleos sin Hyper-Threading podría manejar 4 hilos)?
  • ¿Qué sucede si algo sale mal en un hilo? ¿Se bloquea el proceso, se reinicia el hilo?

Si todos los subprocesos realizan la misma tarea, mantenerlos juntos hará que sea más fácil para el usuario final y los últimos desarrolladores, ya que todo está en un solo lugar.

Si todos los subprocesos tienen acceso a los mismos datos, mantenerlos en el mismo proceso le permitirá compartir esos datos entre subprocesos (aunque tenga en cuenta las condiciones de carrera al cambiar los datos) y reducir la huella de memoria. También podría agrupar los subprocesos para acceder a los datos de los mismos bloques, para que todo pueda almacenarse en la memoria caché de la CPU, lo que reduce el efecto de la latencia de la memoria, aunque esto no es algo que recomendaría intentar.

Dado que muchas de las respuestas dan consejos sobre cómo implementar su proyecto, saber si cada hilo está diseñado para usar completamente la CPU todo el tiempo que se está ejecutando o si se trata de tareas en segundo plano que hacen una pequeña cantidad de trabajo antes Volver a dormir nos ayudará a hacer sugerencias correctas para su situación.

Saber en qué hardware se ejecutará el proceso nos ayudará a proporcionar sugerencias correctas para su situación.

Si falla un hilo, ¿qué ocurre? Si un hilo falla una vez al día, ¿se requiere que el usuario intervenga, detenga el proceso y lo reinicie? Si es así, cualquier trabajo no guardado realizado en los otros hilos se perderá. En este caso, hacer que cada subproceso se ejecute en su propio proceso le daría el beneficio de solo perder el proceso que falló.


La opción 3 de Christian Hayter tiene sentido, pero no siempre es relevante con C#.
Si nos fijamos en la documentation, se indica:

Un sistema operativo ThreadId no tiene ninguna relación fija con un subproceso administrado, ya que un host no administrado puede controlar la relación entre hilos administrados y no administrados. Específicamente, un host sofisticado puede usar la API CLR Hosting para programar muchos hilos administrados contra el mismo hilo del sistema operativo, o para mover un hilo administrado entre diferentes subprocesos del sistema operativo.

Básicamente, esto significa que .Net framework unirá sus hilos si se siente como si fuera una buena idea. Es más probable que esto ocurra si sus procesos utilizan más hilos, mientras que la cantidad total de hilos probablemente será muy similar entre los procesos de múltiples hilos. Como resultado, esperaría que la solución de 1 proceso y 100 hilos utilizara menos subprocesos totales que los 10 procesos, 10 subprocesos cada uno (algo así como 10 a 40, pero habría que verificarlo).

Dicho esto, el framework estará adivinando, por lo que en algunos casos Thread Pools será una mejor opción. Asegúrese de leer primero el documentation, ya que hay algunos casos donde no se deben usar grupos de subprocesos. Puede encontrar un tutorial rápido sobre Pools en MSDN. También hay un thread que analiza cuándo usar Thread Pools.


Si proporciona más información, intentaré dar una respuesta más precisa. De lo contrario, la opción 1 (y posiblemente la opción 3) son las mejores opciones en la mayoría de las situaciones.