VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > c#编程 >
  • C#教程之C#简单多线程同步和优先权用法实例

本文实例讲述了C#简单多线程同步和优先权用法。分享给大家供大家参考。具体分析如下:

本文实例题目如下:

麦当劳有两个做汉堡的厨师(工号:11,12)和三个销售人员(工号:21,22,23)。
厨师生产汉堡,并负责将做好的汉堡放入货架,货架台大小有限,最多放6个汉堡,11和12不能同时往货架台上放汉堡,11具有优先权。
销售人员负责销售食品,三个销售人员取食品时,货架不能为空,三人不能同时取,23优先权最高,21最低。21卖的最快,取得频率最高,22次之。
一天的工作量是销售70个汉堡。

这里先来了解一些概念:
  
阻塞:函数返回结果之前,线程被挂起
非阻塞:函数执行完立即返回,不会阻塞线程
同步:函数没有执行完不返回,线程被挂起;
异步:函数立即返回,结果通过事件或是信号通知调用者;
 
同步消息处理就好比linux中简单的read/write操作,它们需要等待这操作成功才能返回;而异步处理机制就是类似于select/poll之类的多路复用IO操作,当所关注的消息被触发时,由消息触发机制通知触发对消息的处理.

进程:当一个程序运行时,它就是一个进程,进程包括运行中的程序所使用到的内存和系统资源,同时一个进程可以包括多个线程

线程:线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。

多线程:多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。时间片有CPU分配运行!

Thread主要方法:Strart(),Sleep(int),Abort(),Suspend(),Resume()

线程优先级:在C#应用程序中,用户可以设定5个不同的优先级,由高到低分别是Highest,AboveNormal,Normal,BelowNormal,Lowest,在创建线程时如果不指定优先级,那么系统默认为ThreadPriority.Normal。

线程同步(Framework中已经为我们提供了三个加锁的机制,分别是Monitor类、Lock关键字和Mutex类。

① C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待。
在C#中,关键字lock定义如下:

?
1
lock(expression表达式) statement_block

② Monitor主要用法

?
1
2
3
Monitor.Enter(obj);
(expression)
Monitor.Exit(obj);

③ Mutex用法

?
1
2
3
4
Mutex mutex = new Mutex();
mutex.WaitOne();
(expression)
mutex.ReleaseMutex();

举个lock互斥例子(包括多线程使用和多线程优先权、同步使用):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace TestThread
{
  class Program
  {
    private static object lockObject = new object();
    private static object lockObject2 = new object();
    private static int iGetHBnum = 0;
    private static int iPutHBnum = 0;
    private static int count21 = 0;
    private static int count22 = 0;
    private static int count23 = 0;
    private static int count11 = 0;
    private static int count12 = 0;
    static void Main(string[] args)
    {
      Console.WriteLine("主线程运行,线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());
      Thread chushi1 = new Thread(PutHB);
      chushi1.Priority = ThreadPriority.AboveNormal;
      chushi1.Name = "11";
      chushi1.Start();
      Thread chushi2 = new Thread(PutHB);
      chushi2.Priority = ThreadPriority.Normal;
      chushi2.Name = "12";
      chushi2.Start();    
 
      Thread Consume21 = new Thread(GetHB);
      Consume21.Priority = ThreadPriority.Normal;
      Consume21.Name = "21";
      Consume21.Start();
      Thread Consume22 = new Thread(GetHB);
      Consume22.Priority = ThreadPriority.Normal;
      Consume22.Name = "22";
      Consume22.Start();
      Thread Consume23 = new Thread(GetHB);
      Consume23.Priority = ThreadPriority.Normal;
      Consume23.Name = "23";
      Consume23.Start();
      Console.ReadKey();
    }
    public static void PutHB()
    {
      string strID = Thread.CurrentThread.Name.ToString();
      Console.WriteLine("{0}厨师开始制作汉堡,,,", strID);
      while (true)
      {
        if (iPutHBnum >= 6)
        {
          Console.WriteLine("厨师{0},最多放6个汉堡,请让销售员取再放!", strID);
          Thread.Sleep(1000);
        }
        else
        {   
          if (iGetHBnum >= 70 ||count11 + count12 >= 70)
          {
            if (strID == "11")
            {
              Console.WriteLine("厨师{0},在货架放共放{1}汉堡!", strID, count11);
            }
            else if (strID == "12")
            {
              Console.WriteLine("厨师{0},在货架放共放{1}汉堡!", strID, count12);
            }
            break;
          }
          lock (lockObject)
          {
            iPutHBnum++;
          }
          if (strID == "11")
          {
            count11++;
            Console.WriteLine("厨师{0},在货架放已放{1}汉堡! 现在货架有{2}汉堡!", strID,count11, iPutHBnum);
          }
          else if (strID == "12")
          {
            count12++;
            Console.WriteLine("厨师{0},在货架放已放{1}汉堡! 现在货架有{2}汉堡!", strID, count12, iPutHBnum);
          }
        }
      }
    }
    public static void GetHB()
    {
      string strID = Thread.CurrentThread.Name.ToString();
      Console.WriteLine("{0}销售员取汉堡,,,", strID);
        while (true)
        
          if (iPutHBnum <= 0)
          {
            Thread.Sleep(1000);
            Console.WriteLine("{0}货架台已0个汉堡,请等待厨师制作!", strID);
          }
          else
          {
            lock (lockObject2)
            {
              iGetHBnum++;
              iPutHBnum--;
            }
            if (strID == "23")
            {
              count23++;
              Console.WriteLine("23号销售员已销售---{0}!",count23);
              Thread.Sleep(3000);
            }
            else if (strID == "22")
            {
              count22++;
              Console.WriteLine("22号销售员已销售---{0}!", count22);
              Thread.Sleep(2000);
            }
            else if (strID == "21")
            {
              count21++;
              Console.WriteLine("21号销售员已销售---{0}!", count21);
              Thread.Sleep(1000);
            }
          }
          if (iGetHBnum >= 70)
          {
            Console.WriteLine("销售完!");
            if (strID == "23")
            {
              Console.WriteLine("23号销售员销售总数:{0}", count23);
            }
            else if (strID == "22")
            {
              Console.WriteLine("22号销售员销售总数:{0}", count22);
            }
            else if (strID == "21")
            {
              Console.WriteLine("21号销售员销售总数:{0}", count21);
            }
            break;
          }
        }
    }
  }
}

运行结果如下图所示:

lock可以用Monitor,Mutex替代:

?
1
2
3
Monitor.Enter(lockObject);
iPutHBnum++;
Monitor.Exit(lockObject);

或者:

?
1
2
3
mutex1.WaitOne();
iPutHBnum++;
mutex1.ReleaseMutex();

希望本文所述对大家的C#程序设计有所帮助。


相关教程