小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

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

 筆錄收藏 2012-08-19

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


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

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

【注】



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類中提供的一個(gè) 線程入口函數(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); //此處將信號(hào) 傳遞到 設(shè)備類 中。
}
}
while (dwBytesRead > 0 ); 
}
}


while( bLoop ); // End do. 

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


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

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

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

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多