今天同事做培训讲到了线程同步的方法, 其中一个就是用到Semaphore。 Semaphore可以用在不同进程之间的线程同步, 若是在单进程中的线程同步, 使用lock或是Monitor就足够了。 正如其名 旗语就是存在多个任务, 每个任务上都插一个小旗作为互斥信号, 当有一个线程去访问该任务时, 就拔掉小旗 以示其他线程不能访问, 访问完成后再插回小旗使其他线程可以访问。
Demo:
代码
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Threading;
5using System.Diagnostics;
6
7namespace ConsoleApplication1
8{
9
10 class Resources
11 {
12 public string Name;
13
14 public bool isInUse;
15 }
16 class Program
17 {
18 public static Semaphore m_Semaphore;
19 public static List<Resources> m_ResourceList = new List<Resources>();
20 static Random m_Random = new Random();
21
22 public static void ThreadFunc()
23 {
24 while (true)
25 {
26 int resourceID = 0;
27 m_Semaphore.WaitOne();
28
29 for (int i = 0; i < m_ResourceList.Count; i++)
30 {
31 lock (m_ResourceList[i])
32 {
33 if (!m_ResourceList[i].isInUse)
34 {
35 resourceID = i;
36 m_ResourceList[i].isInUse = true;
37 break;
38 }
39 }
40 }
41 Console.WriteLine(string.Format("Thread {0} is using Resource {1}", Thread.CurrentThread.Name, m_ResourceList[resourceID].Name));
42
43 Thread.Sleep(m_Random.Next(10) * 100);
44
45 lock (m_ResourceList[resourceID])
46 {
47 m_ResourceList[resourceID].isInUse = false;
48 }
49
50 m_Semaphore.Release();
51 }
52
53 }
54
55 static void Main(string[] args)
56 {
57 m_Semaphore = new Semaphore(5, 5);
58 //Add five resources to the resource list
59 for (int i = 0; i < 5; i++)
60 {
61 Resources r = new Resources();
62 r.Name = string.Format("{0}", i + 1);
63 r.isInUse = false;
64 m_ResourceList.Add(r);
65 }
66
67 //New 6 threads to access the resources list
68 for (int i = 0; i < 6; i++)
69 {
70 Thread th = new Thread(ThreadFunc);
71 th.Name = string.Format("{0}", i + 1);
72 th.Start();
73 }
74 }
75 }
76}
77
78
2using System.Collections.Generic;
3using System.Text;
4using System.Threading;
5using System.Diagnostics;
6
7namespace ConsoleApplication1
8{
9
10 class Resources
11 {
12 public string Name;
13
14 public bool isInUse;
15 }
16 class Program
17 {
18 public static Semaphore m_Semaphore;
19 public static List<Resources> m_ResourceList = new List<Resources>();
20 static Random m_Random = new Random();
21
22 public static void ThreadFunc()
23 {
24 while (true)
25 {
26 int resourceID = 0;
27 m_Semaphore.WaitOne();
28
29 for (int i = 0; i < m_ResourceList.Count; i++)
30 {
31 lock (m_ResourceList[i])
32 {
33 if (!m_ResourceList[i].isInUse)
34 {
35 resourceID = i;
36 m_ResourceList[i].isInUse = true;
37 break;
38 }
39 }
40 }
41 Console.WriteLine(string.Format("Thread {0} is using Resource {1}", Thread.CurrentThread.Name, m_ResourceList[resourceID].Name));
42
43 Thread.Sleep(m_Random.Next(10) * 100);
44
45 lock (m_ResourceList[resourceID])
46 {
47 m_ResourceList[resourceID].isInUse = false;
48 }
49
50 m_Semaphore.Release();
51 }
52
53 }
54
55 static void Main(string[] args)
56 {
57 m_Semaphore = new Semaphore(5, 5);
58 //Add five resources to the resource list
59 for (int i = 0; i < 5; i++)
60 {
61 Resources r = new Resources();
62 r.Name = string.Format("{0}", i + 1);
63 r.isInUse = false;
64 m_ResourceList.Add(r);
65 }
66
67 //New 6 threads to access the resources list
68 for (int i = 0; i < 6; i++)
69 {
70 Thread th = new Thread(ThreadFunc);
71 th.Name = string.Format("{0}", i + 1);
72 th.Start();
73 }
74 }
75 }
76}
77
78