Ejecutar subprocesos simultáneamente

Iniciado por okik, 31 Enero 2019, 17:26 PM

0 Miembros y 1 Visitante están viendo este tema.

okik

Hola,

He querido comprobar si puedo ejecutar subprocesos Threads simultáneamente:

Código (csharp) [Seleccionar]

using System;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApplication1
{
   public partial class Form1 : Form
   {
       private Thread T1 = new Thread(Thread_1);
       private Thread T2 = new Thread(Thread_2);
       public Form1()
       {
           InitializeComponent();
       }

       private void Form1_Load(object sender, EventArgs e)
       {
           T1.Start();
           T2.Start();
       }
       private void Form1_Shown(object sender, EventHandler e)
       {

       }

       public static void Thread_1()
       {
       MessageBox.Show("Thread_1");
       }

       public static void Thread_2()
       {
       MessageBox.Show("Thread_2");
       }
   }
}



Se supone  que con Threads pueden ejecutarse varios subprocesos al mismo tiempo. La cosa es que  siendo la programación siempre lineal, o sea línea por línea secuencialmente, primero se ejecuta  el subproceso T1.Start() y después T2.Start().

En el código aparecerán un cuadro de mensaje y después el otro, a veces dará la sensación que se muestran simultáneamente pero siempre quedará el cuadro de mensaje "Thread_1" debajo de "Thread_2" porque siempre se muestra primero el Thread_1

La idea era mostrar a tiempo real varios reacciones químicas simuladas con barra de progreso y gráficos paralelos con ajustes de parámetros. Unifiqué todo en un solo proceso estableciendo los valores de antemano, y en un mismo proceso se va mostrando los cambios a tiempo real, sin embargo y creo que es una "ilusión" de simultaneidad ya que para las propiedades de objetos y valores en variables siempre se aplican un valor al primero y luego al segundo secuencialmente. Lo que ocurre es tan rápido que crea es ilusión de simultaneidad pero en realidad no esa así.

Aún teniendo un procesador de varios núcleos ¿Cómo se puede aprovechar esa capacidad del CPU a nivel de código?

He usado 'Buscar' de este foro pero no he encontrado nada al respecto aunque seguro que hay o ya salió el tema.

Saludos

Eleкtro

#1
Cita de: okik en 31 Enero 2019, 17:26 PM
En el código aparecerán un cuadro de mensaje y después el otro, a veces dará la sensación que se muestran simultáneamente pero siempre quedará el cuadro de mensaje "Thread_1" debajo de "Thread_2" porque siempre se muestra primero el Thread_1

Eso no siempre sucede así. He experimentado el código que has puesto tal cual, y te puedo asegurar que con las suficientes iteraciones la suficiente repetición del código habrá veces que el cuadro de mensaje con el texto "Thread_1" estará por encima del otro con el texto "Thread_2" en el orden Z de ventana ( por si no sabes a lo que me refiero: https://en.wikipedia.org/wiki/Z-order ).

Ten en cuenta que el método Thread.Start() es un método asincrónico, por lo tanto tecnicamente no se puede asegurar que Thread_1 finalice su ejecución antes que Thread_2, ni vice versa, pero de todas formas resulta evidente que la mayoría de veces Thread_1 finalizará antes que Thread_2 (y de ahí que la mayoría de veces el cuadro de mensaje con el texto "Thread_2" te aparezca por encima del otro), puesto que la tarea es muy simple y corta (una llamada a la función MessageBox.Show) y principalmente por que ese es el primer thread que estás ejecutando, por lo tanto al escribir una instrucción para llamar primero a Thread_1, y al ser una tarea muy corta la que este thread debe realizar, es normal que casi siempre le de tiempo a finalizar antes que el Thread_2... aunque quizás habría que inspeccionar el código IL compilado para poder hablar con mayor certeza con respecto a la simultaneidad al llamar al método Thread.Start(), pero bueno.

Si quieres una mayor "entropía" o desorden de iteraciones por así decirlo, donde puedas asegurar con mayor certeza (pero no una certeza del 100%, eso no es posible) que una misma tarea se vaya a ejecutrar en múltiples hilos cores de forma simultanea, entonces debes hacer uso de la ejecución en paralelo, o paralelismo. Sencillamente puedes utilizar la clase System.Threading.Tasks.Paralell...

Aquí tienes un ejemplo que sirve como experimentación para demostrar como se puede comprobar cuantas tareas se están ejecutando en paralelo, es decir, de forma simultanea en varios hilos múltiples cores al usar el método Paralell.For / ForEach<T>


PD: esto no quita que los hilos de .NET que creas mediante la clase Thread, o con la clase Task, puedan correr en paralelo.

EDITO: editado unos pequeños fallos (lapsus) que no eran lo que realmente quise expresar cuando escribí el comentario original.

Saludos.








okik

Muy bueno lo de System.Threading.Tasks.Paralell

Sin embargo a mí siempre me quedan los cuadros en el mismo orden, probaré con otra compu a ver.

Saludos