--- Thread basics of multithreaded programming Learning Series

Bloggers declare: I am limited level of technology, if not in place to write, but also please the god pointing. Light spray ...

1: Create a thread

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);
    }
}
The results (the results of each run is not the same):

image

principle:

When we construct a thread, instance, or ParameterizedThreadStart ThreadStart commission will be passed to the constructor, we just need to develop a method name and then run different threads, and C # compiler will re-create these objects back. Then we in the main thread in the usual way to start a thread to run PrintNumbers method.

2: Pause thread

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);
    }
}
The results (not shown fully):

image

working principle:

PrintNumbersWithDelay method call Thread.Sleep, dormant for two seconds, causing the thread to execute the code, before any digital print will wait for a specified time. When a thread is in a sleep state, it will take up as little cpu time. The results we will find the code PrintNumbers method of code than PrintNumbersWithDelay method will separate thread in the first run.

3: thread waits

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);
    }
}
result:

image

working principle:

When the program runs, launched a lengthy thread to digital printing, before printing each number to wait two seconds after the call thread.Join method, which allows us to wait until the thread thread to complete. When the thread is finished thread, the main thread will continue to run.

4: Thread Termination

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);
    }
}
result:

image

working principle:

Main routine and a separate thread running digital printing, call waiting six seconds thread.Abort method, which gives the thread a THreadAbortException injection method, resulting in the thread is terminated. This method not always terminate the thread, the target thread may process the exception and call Tread.ResetAbort way to refuse to be terminated, and therefore do not recommend this method to close the thread.

5: The priority of the thread

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"));
    }
    
}
result:

image

principle:

Define two threads, priority are Highest, Lowest, when to start two threads on all available CPU findings very close, but when set up on a single CPU, the results vary greatly, because most of the time the CPU core in the high-priority thread to run, only to leave the rest of the thread is very little time to run.

6 threads parameter passing

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}");
        }
    }
}
result:

image

principle:
  • The first: to create ThreadSample object and provide a constructor parameter, and then use the object's method CountNumbers start thread
  • The second: use Thread.Start method must accept a single parameter of type object in the process of starting a thread
  • Third: a lambda expression, does not belong to any class given a method to invoke another method with parameters, this method is referred to as closure stopper when any local variables in lambda expressions, C # generates a class, and the variable as a property of the class. This can cause several problems, if you use the same variable in a lambda expression they share the values ​​of variables. When starting threadFour and threadFive thread, printing is 20.
Published 37 original articles · won praise 3 · Views 6336

Guess you like

Origin blog.csdn.net/huan13479195089/article/details/88797254