--- fundamentos de rosca de la programación multihilo Learning Series

Bloggers declaran: ¡Soy nivel limitado de la tecnología, si no en lugar de escribir, sino también por favor, el dios de puntero. aerosol ligero ...

1: Crear un hilo

static void Main(string[] args)
{
    #region 创建线程
    Thread thread = new Thread(PrintNumbers);
    thread.Start();
    PrintNumbers();
    Console.ReadKey();
    #endregion

}

static void PrintNumbers()
{
    Console.WriteLine("Starting...");
    for(int i = 0;i<10;i++)
    {
        Console.WriteLine(i);
    }
}
Los resultados (los resultados de cada ejecución no es el mismo):

imagen

principio:

Cuando se construye un hilo, instancia o comisión ParameterizedThreadStart ThreadStart serán pasados ​​al constructor, sólo tenemos que desarrollar un nombre de método y luego ejecutar diferentes hilos, y compilador de C # a volver a crear estos objetos hacia atrás. Luego en el hilo principal de la forma habitual para iniciar un hilo para ejecutar el método PrintNumbers.

2: hilo Pause

static void Main(string[] args)
{
    #region 暂停线程
    Thread thread = new Thread(PrintNumbersWithDelay);
    thread.Start();
    PrintNumbers();
    Console.ReadKey();
    #endregion

}

static void PrintNumbers()
{
    Console.WriteLine("Starting...");
    for(int i = 0;i<10;i++)
    {
        Console.WriteLine(i);
    }
}

static void PrintNumbersWithDelay()
{
    Console.WriteLine("WithDelayStarting...");
    for (int i = 0; i < 10; i++)
    {
        Thread.Sleep(TimeSpan.FromSeconds(2));
        Console.WriteLine(i);
    }
}
Los resultados (que no se muestran completamente):

imagen

Cómo funciona:

Método PrintNumbersWithDelay llamada Thread.Sleep, latente durante dos segundos, haciendo que el hilo para ejecutar el código, antes de que cualquier impresión digital esperará un tiempo especificado. Cuando un hilo se encuentra en un estado de sueño, tomará el menor tiempo de CPU. Los resultados nos encontraremos con el método PrintNumbers de código de código que el método PrintNumbersWithDelay separará rosca en la primera carrera.

3: hilo espera

static void Main(string[] args)
{
    #region 线程等待
    Console.WriteLine("WithDelayStarting...");
    Thread thread = new Thread(PrintNumbersWithDelay);
    thread.Start();
    thread.Join();
    Console.WriteLine("Thread Completed...");
    Console.ReadKey();
    #endregion

}

static void PrintNumbersWithDelay()
{
    Console.WriteLine("WithDelayStarting...");
    for (int i = 0; i < 10; i++)
    {
        Thread.Sleep(TimeSpan.FromSeconds(2));
        Console.WriteLine(i);
    }
}
resultados:

imagen

Cómo funciona:

Cuando se ejecuta el programa, puesto en marcha un hilo largo para la impresión digital, antes de imprimir cada número que esperar dos segundos después de la llamada Thread.Join método, lo que nos permite esperar hasta que el hilo de rosca al completo. Cuando el hilo es el hilo terminado, el hilo principal seguirá funcionando.

4: Terminación del hilo

static void Main(string[] args)
{
    #region 线程终止
    Console.WriteLine("Starting Program....");
    Thread thread = new Thread(PrintNumbersWithDelay);
    thread.Start();
    Thread.Sleep(TimeSpan.FromSeconds(6));
    thread.Abort();
    Console.WriteLine("A Thread has been aborted....");
    Thread t = new Thread(PrintNumbers);
    t.Start();
    PrintNumbers();
    Console.ReadKey();
    #endregion

}

static void PrintNumbersWithDelay()
{
    Console.WriteLine("WithDelayStarting...");
    for (int i = 0; i < 10; i++)
    {
        Thread.Sleep(TimeSpan.FromSeconds(2));
        Console.WriteLine(i);
    }
}

static void PrintNumbers()
{
    Console.WriteLine("Starting...");
    for (int i = 0; i < 10; i++)
    {
        Console.WriteLine(i);
    }
}
resultados:

imagen

Cómo funciona:

rutina principal y un hilo separado que ejecuta la impresión digital, llamada en espera seis segundos Thread.Abort método, que da el hilo un método de inyección de ThreadAbortException, lo que resulta en el hilo se termina. Este método no siempre terminar el hilo, el hilo de destino puede procesar la excepción y llamada Tread.ResetAbort manera de negarse a ser terminado, y por lo tanto no se recomienda este método para cerrar el hilo.

5: La prioridad del subproceso

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine($"Current thread priority:{Thread.CurrentThread.Priority}");
        //在所有可用的CPU上运行
        Console.WriteLine("Running on all cores available");
        RunThreads();
        Thread.Sleep(TimeSpan.FromSeconds(2));
        Console.WriteLine("Running on a single core");
        //设置单核CPU运行
        Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(1);
        RunThreads();
        Console.ReadKey();
    }

    static void RunThreads()
    {
        var sample = new ThreadSample();
        var threadOne = new Thread(sample.CountNumbers);
        threadOne.Name = "ThreadOne";
        var threadTwo = new Thread(sample.CountNumbers);
        threadTwo.Name = "ThreadTwo";
    
        threadOne.Priority = ThreadPriority.Highest;
        threadTwo.Priority = ThreadPriority.Lowest;
        threadOne.Start();
        threadTwo.Start();
    
        Thread.Sleep(TimeSpan.FromSeconds(2));
        sample.Stop();
    }
}

class ThreadSample
{
    private bool _isStopped = false;
    public void Stop()
    {
        _isStopped = true;
    }

    public void CountNumbers()
    {
        long counter = 0;
        while(!_isStopped)
        {
            counter++;
        }
    
        Console.WriteLine("{0} with {1,11} priority " +
                           "has a count = {2,13} ",
                           Thread.CurrentThread.Name,
                           Thread.CurrentThread.Priority,
                           counter.ToString("N0"));
    }
    
}
resultados:

imagen

principio:

Definir dos temas prioritarios, son lo más bajo posible, cuándo comenzar dos hilos en todos los hallazgos de CPU disponibles muy cerca, pero cuando se creó en una sola CPU, los resultados varían en gran medida, porque la mayoría de las veces el núcleo de la CPU en el hilo de alta prioridad a la ejecución, sólo para dejar el resto de la rosca es muy poco tiempo para correr.

6 hilos de paso de parámetros

class Program
{
    static void Main(string[] args)
    {
        //构造
        var sample = new ThreadSample(5);
        var threadOne = new Thread(sample.CountNumbers);
        threadOne.Name = "ThreadOne";
        threadOne.Start();
        threadOne.Join();
        Console.WriteLine("-----------------------------");
        //Thread.Start
        var threadTwo = new Thread(Count);
        threadTwo.Name = "ThreadTwo";
        threadTwo.Start(5);
        threadTwo.Join();
        Console.WriteLine("-----------------------------");
        //lambda
        var threadThree = new Thread(() => CountNumbers(5));
        threadThree.Name = "ThreadThree";
        threadThree.Start();
        threadThree.Join();
        Console.WriteLine("-----------------------------");

        int i = 10;
        var threadFour = new Thread(() => PrintNumber(i));
        i = 20;
        var threadFive = new Thread(() => PrintNumber(i));
        threadFour.Start();
        threadFive.Start();

        Console.ReadKey();
    }

    static void Count(object iterations)
    {
        CountNumbers((int)iterations);
    }

    static void CountNumbers(int iterations)
    {
        for(int i =1;i<iterations;i++)
        {
            Thread.Sleep(TimeSpan.FromSeconds(0.5));
            Console.WriteLine($"{Thread.CurrentThread.Name} prints {i}");
        }
    }

    static void PrintNumber(int number)
    {
        Console.WriteLine(number);
    }
}

class ThreadSample
{
    private readonly int _iterations;

    public ThreadSample(int iterations)
    {
        _iterations = iterations;
    }

    public void CountNumbers()
    {
        for (int i = 1; i < _iterations; i++)
        {
            Thread.Sleep(TimeSpan.FromSeconds(0.5));
            Console.WriteLine($"{Thread.CurrentThread.Name} prints {i}");
        }
    }
}
resultados:

imagen

principio:
  • El primero: para crear el objeto ThreadSample y proporcionan un parámetro de constructor, y luego usar CountNumbers el método del objeto comienzo de la rosca
  • El segundo: Método de uso hilo.start debe aceptar un único parámetro de tipo de objeto en el proceso de iniciar un hilo
  • En tercer lugar: una expresión lambda, no pertenecen a ninguna clase dada un método para invocar otro método con parámetros, este método se conoce como tapón de cierre cuando las variables locales en las expresiones lambda, C # genera una clase, y la variable como una propiedad de la clase. Esto puede causar varios problemas, si se utiliza la misma variable en una expresión lambda que comparten los valores de las variables. Al iniciar threadFour e hilo threadFive, la impresión es 20.
Publicado 37 artículos originales · ganado elogios 3 · Vistas 6336

Supongo que te gusta

Origin blog.csdn.net/huan13479195089/article/details/88797254
Recomendado
Clasificación