C# .NET Framework 3.5 下 Thread 与 Semaphore 的简单例子

这个例子试图用 C# 3.5 下支持的 Thread 与 Semaphore 来说明,如何让多线程异步(async)处理事情。

比较适合于 A,B 两人抢麦发言的场合。

 1 using System;
 2 using System.Threading;
 3 
 4 namespace testSemaphore
 5 {
 6     class Program
 7     {
 8         Semaphore se = new Semaphore(1, 1);
 9         static void Main(string[] args)
10         {
11 
12             Program p = new Program();
13 
14             p.test();
15 
16             Console.WriteLine("main end, mainthreadid = {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);
17         }
18 
19         void test()
20         {
21             object param1 = new object[] { "Thread A", 1000 };
22             object param2 = new object[] { "Thread B", 20 };
23             
24             Thread t1 = new Thread(new ParameterizedThreadStart(ThreadProc));
25             Thread t2 = new Thread(new ParameterizedThreadStart(ThreadProc));
26 
27             t1.Start(param1);
28             t2.Start(param2);
29         }
30 
31         //void ThreadProc(string name, int startdelay)
32         void ThreadProc(object args)
33         {
34             string name = (string)((object[])args)[0];
35             int startdelay = (int)((object[])args)[1];
36 
37             Console.WriteLine("{0}: COME IN, threadid = {1}", name, System.Threading.Thread.CurrentThread.ManagedThreadId);
38 
39             System.Threading.Thread.Sleep(startdelay);
40 
41             Console.WriteLine("{0}: START, threadid = {1}", name, System.Threading.Thread.CurrentThread.ManagedThreadId);
42 
43             for (int i = 0; i < 10; ++i)
44             {
45                 se.WaitOne();
46 
47                 Random r = new Random();
48 
49                 int s = r.Next(50,1000);
50 
51                 Console.WriteLine("{0}: i = {1}, sleep({2}), threadid = {3}", name, i, s, System.Threading.Thread.CurrentThread.ManagedThreadId);
52 
53                 System.Threading.Thread.Sleep(s);
54 
55                 se.Release();
56             }
57 
58             Console.WriteLine("{0}: END, threadid = {1}", name, System.Threading.Thread.CurrentThread.ManagedThreadId);
59         }
60     }
61 }
62 
63 
64 //main end, mainthreadid = 1
65 //Thread A: COME IN, threadid = 3
66 //Thread B: COME IN, threadid = 4
67 //Thread B: START, threadid = 4
68 //Thread B: i = 0, sleep(168), threadid = 4
69 //Thread B: i = 1, sleep(827), threadid = 4
70 //Thread A: START, threadid = 3
71 //Thread A: i = 0, sleep(913), threadid = 3
72 //Thread B: i = 2, sleep(109), threadid = 4
73 //Thread A: i = 1, sleep(552), threadid = 3
74 //Thread B: i = 3, sleep(175), threadid = 4
75 //Thread A: i = 2, sleep(380), threadid = 3
76 //Thread B: i = 4, sleep(139), threadid = 4
77 //Thread A: i = 3, sleep(768), threadid = 3
78 //Thread B: i = 5, sleep(781), threadid = 4
79 //Thread A: i = 4, sleep(341), threadid = 3
80 //Thread B: i = 6, sleep(523), threadid = 4
81 //Thread A: i = 5, sleep(457), threadid = 3
82 //Thread B: i = 7, sleep(927), threadid = 4
83 //Thread A: i = 6, sleep(961), threadid = 3
84 //Thread B: i = 8, sleep(229), threadid = 4
85 //Thread A: i = 7, sleep(464), threadid = 3
86 //Thread B: i = 9, sleep(481), threadid = 4
87 //Thread B: END, threadid = 4
88 //Thread A: i = 8, sleep(342), threadid = 3
89 //Thread A: i = 9, sleep(865), threadid = 3
90 //Thread A: END, threadid = 3
91 //请按任意键继续. . .

一开始的 Semaphore(1, 1) 代表初始值是1,最大值是1,也就是两人抢一个麦。想像一下,当这个麦被A或B某一个抢到时,se内部的值会等于0,也就是说,没抢到的那位要等到 se 变为1(别人还麦后)。

Semaphore se = new Semaphore(1, 1);

另一个地方就是 给被调用线程传初始参数,这可以通过申明满足 void func( object arg ) 的线程处理函数来满足 delegate ParameterizedThreadStart 需要的形式。

 

通过 Semaphore 可以满足某种在 同步 结构下的 异步等待形式。。比如,A通过消息队列机制让B做事,但A在发送完 “B请开始做事” 后,A要等待B的做事结果,这时,A就应该被阻塞在那里等待。这样就可以通过 new Semaphore(0,1) 来让A 一运行到 se.WaitOne() 时就停在那里的状态,而B在收到做事通知后开始做事,等事情做完后,调用 se.Relase(),就可以让 A脱离等待状态了。

posted @ 2022-02-06 11:14  PencilStart  阅读(505)  评论(0编辑  收藏  举报