zoukankan      html  css  js  c++  java
  • 线程同步之ManualResetEvent类的用法

    笔者的一台激光测厚设备的软件, 它有一个运动线程, 一个激光数据处理线程. 

    运动线程做的事就是由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 Program
    10     {
    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 }

    运行结果如下图:

    本文源代码下载

    原创文章,出处 : http://www.cnblogs.com/hackpig/

  • 相关阅读:
    Out of Hay POJ
    Sum Problem hdu 1001
    N! hdu 1042
    线性表的链式表示和实现(插入删除建空合并)
    NYOJ 1007
    NYOJ 954
    NYOJ 998
    NYOJ 455
    NYOJ 975
    数据结构复习0---线性表
  • 原文地址:https://www.cnblogs.com/hackpig/p/5794797.html
Copyright © 2011-2022 走看看