笔者的一台激光测厚设备的软件, 它有一个运动线程, 一个激光数据处理线程. 运动线程做的事就是由A点移动到B点, 然后再由B点移动回A点.激光处理线程要做的事就是采集指定数量点的激光数据, 随着采集的点数增加, 耗时也会增加.这两个线程就存在线程同步的问题, 预想的标准流程应 ...
笔者的一台激光测厚设备的软件, 它有一个运动get='_blank'>线程, 一个激光数据处理线程.
运动线程做的事就是由A点移动到B点, 然后再由B点移动回A点.
激光处理线程要做的事就是采集指定数量点的激光数据, 随着采集的点数增加, 耗时也会增加.
这两个线程就存在线程同步的问题, 预想的标准流程应该是这样的:
- A点到B点运动开始一瞬间, 通知激光线程开始采集数据
- 激光线程采集数据完成后, 通知运动线程继续, 这时运动线程决定当前是由A到B, 还是由B到A
- 循环执行上述的动作.
这样的线程同步要求, 可以使用C#的一个封装windows内核信号量的类ManualResetEvent来实现, 它是笔者用得最多的一个类. 所以在这里重点记录下来.
ManualResetEvent的功能我们先做一个简要说明:
ManualResetEvent可以通知一个或多个正在等待的线程已发生事件,允许线程通过发信号互相通信,来控制线程是否可心访问资源
当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态。此线程可被视为控制 ManualResetEvent。调用 ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。
一旦它被终止,ManualResetEvent 将保持终止状态,直到它被手动重置。即对 WaitOne 的调用将立即返回。
可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则为 false。
看理论要结合代码验证, 这样更容易明白.
下面给出演示代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading; 6 7 namespace ManualResetEventState 8 { 9 class Program10 {11 static ManualResetEvent _mre = new ManualResetEvent(false);12 static void Main(string[] args)13 {14 Console.WriteLine("输入1为Set() 开始运行");15 Console.WriteLine("输入2为Reset() 暂停运行");16 Thread[] _threads = new Thread[3];17 18 for (int i = 0; i < _threads.Count(); i++)19 {20 _threads[i] = new Thread(ThreadRun);21 _threads[i].Start();22 }23 24 while (true)25 {26 switch (Console.ReadLine())27 {28 case "1":29 _mre.Set();30 Console.WriteLine("开始运行");31 break;32 case "2":33 _mre.Reset();34 Console.WriteLine("暂停运行");35 break;36 default:37 break;38 }39 }40 }41 42 static void ThreadRun()43 {44 int _threadID = 0;45 while (true)46 {47 _mre.WaitOne();48 _threadID = Thread.CurrentThread.ManagedThreadId;49 Console.WriteLine("current Tread is " + _threadID);50 Thread.Sleep(TimeSpan.FromSeconds(2));51 52 }53 }54 }55 }
原标题:线程同步之ManualResetEvent类的用法
关键词:线程
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。