您当前的位置: 首页 >  c#

光怪陆离的节日

暂无认证

  • 3浏览

    0关注

    1003博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

C#基本--线程的使用

光怪陆离的节日 发布时间:2022-10-10 09:33:48 ,浏览量:3

  1. 概述与概念 1.1. 入门线程小例子 C#支持通过多线程并行地执行代码,一个线程有它独立的执行路径,能够与其它的线程同时地运行。一个C#程序开始于一个单线程,这个单线程是被CLR和操作系统(也称为“主线程”)自动创建的,并具有多线程创建额外的线程。

class ThreadTest

{

   static void Main()

  {

          Threadt = new Thread (WriteY);

           t.Start();                         

           while (true) Console.Write ("x"); 

   }

   static void WriteY()

   {

          while (true)Console.Write ("y");  

   }

} 主线程创建了一个新线程“t”,它运行了一个重复打印字母"y"的方法,同时主线程重复打印字母“x”。CLR分配每个线程到它自己的内存堆栈上,来保证局部变量的分离运行。在接下来的方法中我们定义了一个局部变量,然后在主线程和新创建的线程上同时地调用这个方法。

static void Main()

{

new Thread (Go).Start();

Go();

}

static void Go()

{

for (int cycles = 0; cycles < 5; cycles++)Console.Write ('?');

} 在这里插入图片描述 变量cycles的副本分别在各自的内存堆栈中创建,输出也一样,可预见,会有10个问号输出。当线程们引用了一些公用的目标实例的时候,他们会共享数据。下面是实例:

class ThreadTest

{

   bool done;

   static void Main()

  {

          ThreadTest tt = new ThreadTest();  

           new Thread (tt.Go).Start();

           tt.Go();

   }

   void Go()

   {

          if (!done) { done = true; Console.WriteLine("Done"); }

    }

}

因为在相同的ThreadTest实例中,两个线程都调用了Go(),它们共享了done字段,这个结果输出的是一个"Done",而不是两个。

  静态字段提供了另一种在线程间共享数据的方式,下面是一个以done为静态字段的例子:

class ThreadTest

{

static bool done;   

static void Main()

{

    new Thread (Go).Start();

    Go();

}

static void Go()

{

    if (!done) { done = true; Console.WriteLine("Done"); }

}

}

上述两个例子足以说明, 另一个关键概念, 那就是线程安全(或反之,它的不足之处! ) 输出实际上是不确定的:它可能(虽然不大可能) ,“Done” ,可以被打印两次。然而,如果我们在Go方法里调换指令的顺序,"Done"被打印两次的机会会大幅地上升:

static void Go()

{

if (!done){ Console.WriteLine (“Done”); done = true; }

} 问题就是一个线程在判断if块的时候,正好另一个线程正在执行WriteLine语句,还没有将done设置为true。补救措施是当读写公共字段的时候,提供一个排他锁;C#提供了lock语句来达到这个目的。

class ThreadSafe

{

static bool done;

static object locker= new object();

static void Main()

{

    new Thread (Go).Start();

    Go();

}

static void Go()

{

    lock (locker)

    {

        if (!done) { Console.WriteLine ("Done");done = true; }

    }

}

}

当两个线程争夺一个锁的时候(在这个例子里是locker),一个线程等待,或者说被阻止到那个锁变的可用。在这种情况下,就确保了在同一时刻只有一个线程能进入临界区,所以"Done"只被打印了1次。代码以如此方式在不确定的多线程环境中被叫做线程安全。

临时暂停,或阻止是多线程的协同工作,同步活动的本质特征。等待一个排它锁被释放是一个线程被阻止的原因,另一个原因是线程想要暂停或Sleep一段时间:

Thread.Sleep(TimeSpan.FromSeconds (30));

一个线程也可以使用它的Join方法来等待另一个线程结束:

static void Main()

{

Thread t = new Thread (WriteY);

t.Start();    

t.Join();                     

for(int i=0;i            
关注
打赏
1665731445
查看更多评论
0.1498s