乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      WaitForMultipleObjects,CreateEvent()函數(shù)在線程通信中的...

       筆錄收藏 2012-08-19

      (1) 在一個表示某種設(shè)備的C++類代碼,其中創(chuàng)建了一個命名的“事件對象”


      bool SomeDevide::Open( int iPortNumber )


      。。。

      // Create the event that will get Set when data comes in for us to read
      m_hReadEvent = CreateEvent(NULL,FALSE,FALSE, L"Data Available for read" );

      。。。

      }

      (2) 該設(shè)備類為了不斷的和底層硬件通信(通過一個串口類實現(xiàn))必須啟動一個線程來讀取設(shè)備發(fā)來的數(shù)據(jù)或者控制設(shè)備的狀態(tài)。奇怪的是我光發(fā)現(xiàn)在該線程中使用了WaitForMultipleObjects(。。。)來等待(1)中創(chuàng)建的事件,但是在設(shè)備類中沒有發(fā)現(xiàn)那句語句來設(shè)置該“事件”為有信號。

      /**
      * Waits for data arrival event to be signalled from serial class instance in m_Serial
      * Once it gets notified of data arrival, it tries to read 128 chars
      */

      static DWORD DevideWaitForReadThread( LPVOID pIn )

      {
      HANDLE hEvents[2];
      hEvents[0] = m_hReadEvent;
      hEvents[1] = m_hStopEvent;

      。。。

      // LOOP 1 : Wait for data to arrive and read it.
      do
      {
      DWORD dwEvent = WaitForMultipleObjects( 2, hEvents, FALSE, 1000 );

      。。。

      }

      (3)最后才發(fā)現(xiàn)是通過 設(shè)備類 所依賴的 串口類 來向該“事件對象”發(fā)送信號的。這里面就用到了“命名事件對象”的技術(shù)了;如果在你的程序中有多處使用CreateEvent(。。。)創(chuàng)建同名的事件對象,那么在這些語句中只有第一次執(zhí)行CreateEvent時windows系統(tǒng)才真正在內(nèi)核中創(chuàng)建該事件的內(nèi)核對象,后續(xù)語句都是返回先前創(chuàng)建的事件對象句柄。

      【注】



      HANDLE CreateEvent( 

      LPSECURITY_ATTRIBUTES lpEventAttributes, 

      BOOL bManualReset, 

      BOOL bInitialState, 

      LPTSTR lpName ); 
      Return Values

      A handle to the event object indicates success. If the named event object existed before the function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS. NULL indicates failure. To get extended error information, call GetLastError. 

      If lpName matches the name of an existing semaphore, mutex, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space. 

      我將串口類中的構(gòu)造函數(shù)列于下面以供參考:

      EmbeddedSerial::EmbeddedSerial()
      {
      。。。

      /* Events to stop the read thread */
      m_hStopReadThread = CreateEvent( NULL, FALSE, FALSE, L"Stop Read Thread" ); 

      /* Events to signal that the read thread have stopped */
      m_hReadThreadDown = CreateEvent( NULL, FALSE, FALSE, L"Read thread has shut down" );

      m_hReadEvent = CreateEvent(NULL,FALSE,FALSE, L"Data Available for read" ); 

      。。。 





      以下是EmbededSerial類中提供的一個 線程入口函數(shù): 

      static DWORD ReadThread( LPVOID lp );
      該函數(shù)的定義如下: 

      DWORD EmbeddedSerial::ReadThread( LPVOID lp )
      {
      ((EmbeddedSerial*)lp)->ReadThreadObj();
      return 0;


      該函數(shù)中調(diào)用的ReadThreadObj()定義如下: 

      /*
      * The thread responsible for reading data. Waits for one of 2 events
      * An internal event to signal data arrival at the port - in which case it reads all available data from port into ring buffer
      * m_hStopReadThread - in which case th thread ends
      */
      void EmbeddedSerial::ReadThreadObj( void )
      {
      。。。

      DWORD dwWaitMask = EV_RXCHAR;

      DWORD dwError =0; 

      unsigned char cTemp[READ_BLOCK_SIZE]; 

      bool bLoop = true; 

      SetCommMask(m_hCommPort, dwWaitMask );

      do
      {
      if (WaitForSingleObject( m_hStopReadThread, 100) == WAIT_OBJECT_0)
      {
      // Quit the thread ??
      bLoop = false;
      }
      else
      {
      DWORD dwMask;
      if( GetCommMask( m_hCommPort, &dwMask ) )
      {
      if( EV_RXCHAR == (dwMask & EV_RXCHAR) )
      {
      // Read data in blocks of 128 bytes
      do
      {
      ReadFile( m_hCommPort, cTemp, READ_BLOCK_SIZE,&dwBytesRead,NULL);

      if( dwBytesRead > 0 ) 
      {
      // update the last tick count of read data
      m_TickCountAtLastRead = GetTickCount();

      // Put the data into the ring buffer for Read data
      AddDataToRingBuffer(cTemp, dwBytesRead); 

      // signal more data
      SetEvent(m_hReadEvent); //此處將信號 傳遞到 設(shè)備類 中。
      }
      }
      while (dwBytesRead > 0 ); 
      }
      }


      while( bLoop ); // End do. 

      // Tell the dtr we have shut down
      SetEvent( m_hReadThreadDown );


      【注】所有整個線程的交換過程是這樣的: 

      串口(硬件接收器)接收到數(shù)據(jù)后會置位串口的狀態(tài)位(狀態(tài)寄存器)----->接著串口驅(qū)動程序(C++類實現(xiàn)的串口驅(qū)動程序)中的讀寫線程使用if( GetCommMask( m_hCommPort, &dwMask ) )取得當(dāng)前串口的狀態(tài),以便判斷是否接收到了數(shù)據(jù),如果接受到數(shù)據(jù)則將數(shù)據(jù)放入串口驅(qū)動所維護的緩沖區(qū)中,并且通過 

      SetEvent(m_hReadEvent);將數(shù)據(jù)已經(jīng)準(zhǔn)備好信號發(fā)生到 設(shè)備類中------->然后由設(shè)備類中啟動的設(shè)備線程讀取串口線程所送上來的數(shù)據(jù)并進行后續(xù)解析。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多