• C#线程从陌生到熟悉(1)


    C#线程从陌生到熟悉(1)
        谈到线程(Thread),大家应该不会陌生。和他相近的还有一个进程的概念(Process)。那首先我们先来熟悉他们的概念,以及他们之间的关系。
    什么是进程?
    当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。
    而一个进程又是由多个线程所组成的。
    什么是线程?
    线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。
    他们的关系?
    线程根进程既有联系又有区别。进程是代码在数据集的一次执行,是系统资源分配的基本单位。任何一个线程必然在一个进程中运行;而一个进程至少拥有一个线程,否则无法执行。事实上,每个进程都有一个主线程,该线程所拥有的其他线程都是由主线程创建的。如果我们s结束一个进程的主线程,就会结束该进程的所有其他线程,也就结束整个进程!

    我们可以这么理解:真正去运行代码是线程!而进程只是为运行代码配置所运行的系统资源。几个线程共同运行完成某项功能,组织了一次代码执行过程!这样就有了进程!

    C#里面是Thread类来表示线程的!那我们先来看看Thread类的定义。
    [ComVisibleAttribute(true)]
    [ClassInterfaceAttribute(ClassInterfaceType.None)]
    public sealed class Thread : CriticalFinalizerObject,
     _Thread
    {
     ...



    }
    [ComVisibleAttribute(true)]这个表示控制程序集中个别托管类型、成员或所有类型对 COM 的可访问性。
    [ClassInterfaceAttribute(ClassInterfaceType.None)]为公开给 COM 的类指定要生成的类接口的类型(如果有接口生成)。
    在从 CriticalFinalizerObject 类派生的类中,公共语言运行库 (CLR) 保证所有关键终止代码都有机会执行,即使是在 CLR 强行卸载应用程序域或中止线程的情况中(只要终结器遵守 CER 的规则);
    _Thread此接口用于从非托管代码访问托管类,不应从托管代码调用。
    这里注意的Thread类在.net是声明sealed,他是无法被继承的!这和Java的区别挺大的!
    他有4个构造函数,我们主要看下其中两个就行了!
    [SecuritySafeCritical]
    public Thread(ParameterizedThreadStart start);
    [SecuritySafeCritical]
    public Thread(ThreadStart start);
    ParameterizedThreadStart 和ThreadStart都为一个委托,其中第一个委托表示带参数的委托,类型为obj,后面一个为不带参数的委托。他们都被标记了[ComVisible(false)]表示不能对COM+进行访问!
    通过Thread的一些静态属性能够得到当前的上下文,当前运行的进程等等!通过他的静态方法能获得他的运行应用域等等!
    下面我们看个例子,

     1  class Program
    2 {
    3 static void Main(string[] args)
    4 {
    5 ThreadStart tspx = new ThreadStart(PrintX);
    6 ThreadStart tspy = new ThreadStart(PrintY);
    7 ParameterizedThreadStart ptsp = new ParameterizedThreadStart(PrintParam);
    8 Thread t1 = new Thread(tspx);
    9 Thread t2 = new Thread(tspy);
    10 Thread t3 = new Thread(ptsp);
    11
    12 t1.Start();
    13 t2.Start();
    14 t3.Start("123");
    15 Thread.Sleep(300);
    16
    17 }
    18 public static void PrintX()
    19 {
    20 int i = 1;
    21 while (i++<50)
    22 {
    23 Console.Write("X");
    24 }
    25 }
    26 public static void PrintY()
    27 {
    28 int i = 1;
    29 while (i++ < 50)
    30 {
    31 Console.Write("Y");
    32 }
    33 }
    34 public static void PrintParam(object s)
    35 {
    36 int i = 1;
    37 while (i++ < 50)
    38 {
    39 Console.Write(s.ToString());
    40 }
    41 }
    42
    43 }

    例子是比较简单,运行之后的结果往往比较随机的!只需要把运行的次数调高点就可!注意ParameterizedThreadStart这个参数是Object类型的!从这个例子可看出,这些线程是杂乱的运行的!只要将主线程结束,整个应用程序就会结束,而结束其他线程则不会!

    请看下面的例子,

     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5 using System.Threading;
    6
    7 namespace ConsoleApplication3
    8 {
    9 class Program
    10 {
    11 static void Main(string[] args)
    12 {
    13 Thread t = new Thread(PrintX);
    14 t.Start();
    15 Thread.CurrentThread.Name = "Main";
    16 Console.WriteLine("主线程的应用域{0},ID为{1}", Thread.GetDomain().ToString(), Thread.GetDomainID());
    17 Console.WriteLine("主线程的名字为{0},HashCode为{1}", Thread.CurrentThread.Name, Thread.CurrentThread.GetHashCode());
    18
    19 }
    20 static void PrintX ()
    21 {
    22 Thread.CurrentThread.Name = "t1";
    23 Console.WriteLine("t1线程的应用域{0},ID为{1}", Thread.GetDomain().ToString(), Thread.GetDomainID());
    24 Console.WriteLine("t1线程的名字为{0},HashCode为{1}", Thread.CurrentThread.Name, Thread.CurrentThread.GetHashCode());
    25 }
    26 }
    27 }



    这个例子运行如下图所示,

    这里,通Thread的一些静态属性可以获得我们一些想要的东西!这一点在平时用的也比较多!
    好了,今天就写了这么多了!

     

  • 相关阅读:
    LinQ Group By
    sql server 还原数据库后,删除用户,提示数据库主体在该数据库中拥有架构,无法删除解决方法
    各种网站资源
    Easyui TreeGrid数据源
    MVC中创建自定义视图的t4模板
    栈溢出练习
    Stack Canary
    攻防世界pwn之新手练习区
    开源 PetaPoco 扩展~一个小型轻巧的ORM~
    linux调度全景指南
  • 原文地址:https://www.cnblogs.com/enuo/p/2277988.html
Copyright © 2020-2023  润新知