当前位置:编程学习 > C#/ASP.NET >>

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

 

互斥与同步

今天我们来看互斥与同步,互斥与同步一直线程操作方面的至关重要的一部份.首先来看下他们之间的概念.

互斥和同步都是在并发环境下编程特有的问题.并发是指宏观上多个线程同时进行而某一时刻只有一个线程运行,即宏观并行微观串行.大家应该都知道时间片的概念,上面的话应该很容易理解的.并发环境下,不能有两个以上(包括两个)某类特殊的资源,就叫互斥.这类特殊资源也被称为临界资源,例如字符串缓冲区,文件,实例对象等.同步是指多个线程互相通信,互相等待从而使进程按照一定顺序往前推进.其实特殊的资源应该就是经常用到的变量与对象只不过在某一时刻只能由一个线程操作他.

1.互斥

.NET公共运行库提供了几种方法实现对临界资源的互斥访问.

首先看Monitor这个类

[ComVisible(true)]

public static class Monitor

{

[SecuritySafeCritical]

public static void Enter(object obj);

[SecuritySafeCritical]

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]

public static void Exit(object obj);

[SecuritySafeCritical]

public static void Pulse(object obj);

public static bool TryEnter(object obj);

[SecuritySafeCritical]

public static bool Wait(object obj);

.....

}

这几个方法简单介绍,Enter获取对象锁(参数obj),Exit释放对象锁,Pulse通知等待队列中的线程锁定对象状态的更改,TryEnter尝试获取对象锁,Wait释放对象上的锁并阻止当前线程,直到它重新获取该锁。

下面来看个例子:

 1 using System;

 2 using System.Collections.Generic;

 3 using System.Linq;

 4 using System.Text;

 5 using System.Threading;

 6

 7 namespace ConsoleApplication8

 8 {

 9     class Program

10     {

11         int x = 100;

12         static void Main(string[] args)

13         {

14             Program p = new Program();

15             Thread t1 = new Thread(p.MyWork1);

16             Thread t2 = new Thread(p.MyWork2);

17             t1.Start();

18             t2.Start();

19         }

20         void MyWork1()

21         {

22             try

23             {

24                 Monitor.Enter(this);

25                 while (true)

26                 {

27                   

28                     if (x < 1) { break; }

29                     x--;

30                     Console.WriteLine("调用MyWork1()");

31                 }

32             }

33             finally

34             {

35                 Monitor.Exit(this);

36             }

37         }

38         void MyWork2()

39         {

40           

41             try

42             {

43                 Monitor.Enter(this);

44                 while (true)

45                 {

46

47                     if (x < 1) { break; }

48                     x = x - 2;

49                     Console.WriteLine("调用MyWork2()");

50

51                 }

52             }

53             finally

54             {

55                 Monitor.Exit(this);

56             }

57         }

58     }

59 }

输出结果为

 

\

 

结果全为MyWork1的调用,如果将Monitor.Enter(this)和Monitor.Exit(this)注释起来的话,在运行的话,就会出现MyWork1和Mywork2都在运行了.还有可以将MyWork1中的x<1改成10那运行结果为

 

\

 

可见MyWork1先运行了,当他释放完锁之后MyWork2获取到对象所之后才运行.从这个例子我们可以看出Monitor.Enter(this)和Monitor.Exit(this)的用法.按照我的理解:Monitor.Enter(this)会一直等待,直到获到对象锁.对于这个猜测,我们可以在MyWork2的Monitor.Enter(this)加一句输出语句.可以看这个输出结果会在控制台上.

将上面的例子稍加更改,来重点说下TryEnter,Wait,Pulse这三函数的用法及相关解释.

先看代码

 

 1 using System;

 2 using System.Collections.Generic;

 3 using System.Linq;

 4 using System.Text;

 5 using System.Threading;

 6

 7 namespace ConsoleApplication8

 8 {

 9     class Program

10     {

11         int x = 100;

12         static void Main(string[] args)

13         {

14   &nbs

补充:软件开发 , C# ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,