zoukankan      html  css  js  c++  java
  • 基元线程同步构造之 在一个内核构造可用时调用一个方法

      让一个线程不确定的等待一个内核对象进入可用状态,这对线程的内存资源来说是一种浪费。因此,线程池提供了一种方式,在一个内核对象变得可用的时候调用一个方法。这是通过System.Threading.ThreadPool类的静态RegisterWaitForSingleObject方法来实现的。该方法有几个重载的版本,但这些版本全都是很相似。以下是一个较常用的重载版本的原型:

      

    public static RegisteredWaitHandle RegisterWaitForSingleObject(
       WaitHandle waitObject,
       WaitOrTimerCallback callback,
       Object state,
       Int32 millsecondsTimeoutInterval,
       Boolean executeOnlyOnce
    );

    参数说明:

      waitObject:标识了你希望线程池等待的内核对象,由于这个参数的类型是抽象基类WaitHandle,所以可以指定从这个基类派生的任何类。具体的说,可以传递          对一个Semaphore、Mutex、AutoResetEvent或者ManualResetEvent对象的引用。

      callback:标识了希望线程池线程调用的方法,这个回调方法必须匹配System.Threading.WaitOrTimerCallback委托:

              public delegate void WaitOrTimerCallback(Object state,Boolean timedOut)

      state:允许指定一些状态数据,线程池线程调用回调方法时,会将这个状态传给回调方法;如果没有特殊的状态数据需要传递,就传递null.

      millsecondsTimeoutInterval:指定了线程池在等待内核对象收到信号时的超时时间。一般传递 Timeout.Infinite(-1),将超时时间设为“无限长”。通俗点就是每                间隔多少时间执行一次 callback方法。

      executeOnlyOnce:为true时,线程池线程只执行回调方法一次,为false时,那么内核对象每次收到信号,线程此线程都会执行回调方法。

    调用回调方法是,会向它传递状态数据和一个名为timedOut的Boolean值(通俗的说也就是在规定的时间millsecondsTimeoutInterval内,内核对象是否收到了信号),如果timedOut为false,方法知道他之所以被调用,是因为内核对象收到了信号。

         如果timedOut为true,方法知道它之所以被调用,是因为内核对象在指定的时间内没收到信号。

       注意:RegisterWaitForSingleObject方法返回的是对一个RegisteredWaitHandle对象的引用。这个对象标识了线程池线程正在它上面等待的内核对象。如果处于任何原因,你的应用程序向告诉线程池停止监视已登记的等待句柄,应用程序可以调用RegisteredWaitHandle的Unregister方法: 

    public Boolean Unregister(WaitHandle waitObject);

      参数说明: waitObject参数指出,针对已登记等待句柄的、队列中的所有工作项都执行好之后,你想如何收到通知。

        如果不想接收通知,应该为这个参数传递null.

        如果传递的是对一个WaitHandle派生对象的有效引用,那么针对已登记的等待句柄的所有待决的工作项都执行完毕后,线程池线程就会向对象发出信号。

      以下代码演示了如果在一个AutoResetEvent对象收到信号之后,让一个线程池线程调用一个方法:

      

     1 // This example shows how a Mutex is used to synchronize access
     2 // to a protected resource. Unlike Monitor, Mutex can be used with
     3 // WaitHandle.WaitAll and WaitAny, and can be passed across
     4 // AppDomain boundaries.
     5 
     6 using System;
     7 using System.Threading;
     8 
     9 internal static class RegisteredWaitHandleDemo
    10 {
    11     public static void Main()
    12     {
    13         // Construct an AutoResetEvent (initially false)
    14         AutoResetEvent are = new AutoResetEvent(false);
    15 
    16         // Tell the thread pool to wait on the AutoResetEvent告诉线程池在AutoResetEvent上等待
    17         RegisteredWaitHandle rwh = ThreadPool.RegisterWaitForSingleObject(
    18            are,             // Wait on this AutoResetEvent 在这个AutoResetEvent上等待
    19            EventOperation,  // When available, call the EventOperation method 如果可用,就调用EventOperation方法
    20            null,            // Pass null to EventOperation 向EventOperation传递null
    21            5000,            // Wait 5 seconds for the event to become true 等5秒事件变成true,就执行 EventOperation回调方法,
                       // 也就是每间隔5秒执行一次EventOperation
    22 false); // Call EventOperation everytime the event is true 每次事件为true时,都调用 EventOperation 23 24 // Start our loop 25 Char operation = (Char)0; 26 while (operation != 'Q') 27 { 28 Console.WriteLine("S=Signal, Q=Quit?"); 29 operation = Char.ToUpper(Console.ReadKey(true).KeyChar); 30 if (operation == 'S') are.Set(); // User want to set the event 31 } 32 33 // Tell the thread pool to stop waiting on the event,此处传递的是NULL,就不会向任何对象发送信号 34 rwh.Unregister(null); 35 } 36 37 // This method is called whenever the event is true or 38 // when 5 seconds have elapsed since the last callback/timeout 39 private static void EventOperation(Object state, Boolean timedOut) 40 { 41 Console.WriteLine(timedOut ? "Timeout" : "Event became true"); 42 } 43 }

    以下的示例代码中 增加了取消登记时候发送信号的功能:

      

     1 // This example shows how a Mutex is used to synchronize access
     2 // to a protected resource. Unlike Monitor, Mutex can be used with
     3 // WaitHandle.WaitAll and WaitAny, and can be passed across
     4 // AppDomain boundaries.
     5 
     6 using System;
     7 using System.Threading;
     8 
     9 internal static class RegisteredWaitHandleDemo
    10 {
    11     public static void Main()
    12     {
    13         // Construct an AutoResetEvent (initially false)
    14         AutoResetEvent are = new AutoResetEvent(false);
    15 
    16         AutoResetEvent arereult = new AutoResetEvent(false);
    17 
    18         System.Threading.Thread thr = new Thread(new ParameterizedThreadStart(TestUnregistered));
    19         thr.Start(arereult);
    20 
    21         // Tell the thread pool to wait on the AutoResetEvent
    22         RegisteredWaitHandle rwh = ThreadPool.RegisterWaitForSingleObject(
    23            are,             // Wait on this AutoResetEvent
    24            EventOperation,  // When available, call the EventOperation method
    25            null,            // Pass null to EventOperation
    26            5000,            // Wait 5 seconds for the event to become true
    27            false);          // Call EventOperation everytime the event is true
    28 
    29         // Start our loop
    30         Char operation = (Char)0;
    31         while (operation != 'Q')
    32         {
    33             Console.WriteLine("S=Signal, Q=Quit?");
    34             operation = Char.ToUpper(Console.ReadKey(true).KeyChar);
    35             if (operation == 'S') are.Set(); // User want to set the event
    36         }
    37 
    38         // Tell the thread pool to stop waiting on the event 取消注册后,向arereult发送信号,TestUnregistered就会解除阻塞
    39         rwh.Unregister(arereult);
    40 
    41         Console.ReadLine();
    42     }
    43 
    44     // This method is called whenever the event is true or
    45     // when 5 seconds have elapsed since the last callback/timeout
    46     private static void EventOperation(Object state, Boolean timedOut)
    47     {
    48         Console.WriteLine(timedOut ? "Timeout" : "Event became true");
    49     }
    50 
    51     private static void TestUnregistered(object waithandle)
    52     {
    53         ((AutoResetEvent)waithandle).WaitOne();
    54 
    55         Console.WriteLine(" Test is TestUnregistered ");
    56     }
    57 
    58 }

      

     以上的理解来源于 CLR 书中的理解。。。。。欢迎各位大侠们拍砖指正错误之处。。。。。。。。。。

  • 相关阅读:
    nginx服务与nfs服务
    linux基础(3)
    Linux基础(4)
    Linux命令基础(2)
    Linux命令基础(1)
    HTML——表单验证、正则表达式、事件
    css修改鼠标指针的形状
    ajax请求tab切换重新渲染Echarts图表
    5种状态下的HTTP状态码
    vue&Angular&React的优缺点
  • 原文地址:https://www.cnblogs.com/huaan011/p/3580406.html
Copyright © 2011-2022 走看看