4가지 방법이 있다.


 방법

요약 

 디바이스 커널 오브젝트의 시그널링

 단일의 장치에 대해 다수의 I/O 요청을 수행하는 경우 적합하지 않다.  특정스레드가 I/O요청을 하고 다른 

스레드가 완료 통지를 수신할 수 있다.

 이벤트 커널 오브젝트의 시그널링

 단일의 장치에 대해 다수의 I/O 요청을 수행할 수 있다. 특정스레드가 I/O요청을 하고 다른 

스레드가 완료 통지를 수신할 수 있다.

 얼러터블 I/O 사용

 단일의 장치에 대해 다수의 I/O 요청을 수행할 수 있다. 항상 I/O 요청을 한 스레드가 완료 통지를 수신한다.

 IOCP 사용

 단일의 장치에 대해 다수의 I/O 요청을 수행할 수 있다. 특정 스레드가 I/O 요청을 하고 다른 스레드가 완료

통지를 수신할 수 있다. 


■ 디바이스 커널 오브젝트의 시그널링

말 그대로 디바이스 커널 오브젝트의 시그널링을 체크하는 방식이다.

예로, CreateFile() 의 결과값 (파일 디바이스의 커널 오브젝트) 을 가지고 WaitForSingleObject()를 이용하여

작업 완료시까지 대기하는 방식이다.

 

"단일 장치에 대해 다수의 I/O 요청을 수행하는 경우 적합하지 않다." 라는 의미는

동시에 두 개의 I/O 요청을 한 경우 완료되었을 때 어떤 요청의 완료인지에 대해 명확하게

파악을 할 수가 없기 때문에 적합하지 않다 라는 의미이다.

 

단적인 사용 예>

BOOL bReadDone = ::ReadFile(hFile, bBuffer, 100, NULL, &o);
DWORD dwError = ::GetLastError();

 

if ( !bReadDone && (dwError == ERROR_IO_PENDING))
{
    WaitForSingleObject(hFile, INFINITE); 
    bReadDone = TRUE;
}

 

if (bReadDone) { // 성공 }

 

■ 이벤트 커널 오브젝트의 시그널링

이벤트 커널 오브젝트의 경우는 OVERLAPPED 의 hEvent 필드를 이용하기 때문에, 어떠한 I/O 요청인지

판단을 할 수가 있다. 이 때 반드시 각 요청별로 서도 다른 이벤트 커널 오브젝트를 생성해야 한다.

 

단적인 사용 예>

OVERLADDPED oRead = {0};

oRead.hEvent = CreateEvent();

::ReadFile(hFile, bBuffer, 100, NULL, &oRead);

 

OVERLADDPED oWrite = {0};

oRead.hEvent = CreateEvent();

::WriteFile(hFile, bBuffer, _countof(bBuffer), NULL, &oWrite);

HANDLE h[2];

h[0] = oRead.hEvent;

h[1] = oWrite.hEvent;

 

DWORD dw = WaitForMultipleObjects(2, h, FALSE, INFINITE);

// Read가 끝났는지, Write가 끝났는지 확인 가능하다.

 

■ 얼러터블 I / O

스레드가 생성되면 시스템은 각 스레드별로 비동기 프로시저 콜 (APC) 큐라는 것을 하나씩 생성한다.

비동기 I/O 요청을 전달하는 함수(ReadFileEx, WriteFileEx)를 호출하는 경우

디바이스 드라이버에게 I//O 작업 완료 통지를 스레드의 APC큐에 삽입해 줄 것을 요청할 수 있다.


VOID WINAPI CompletionRoutine (DWORD dwError, DWORD dwNumBytes, OVERLAPPED* po)
{

    // dwError와 dwNumBytes는 po-> 를 이용해서도 구할 수 있다.
    wprintf(L"po->Internal : %d, dwError : %d\n", po->Internal, dwError); 
    wprintf(L"po->InternalHigh : %d, dwNumBytes : %d\n", po->InternalHigh, dwNumBytes);
}

 

int wmain(void)

{

    ReadFileEx (hFile, buffer, buffer count, &overladdped, CompletionRoutine);

   

    // 스레드가 얼러터블 상태가 되면, 시스템은 APC큐의 내용을 확인하여 큐에 삽입된 모든 항목에 대해

    // 컴플리션 루틴을 호출해 준다. 아래는 해당 스레드를 얼러터블 상태로 만드는 함수인 SleepEx을 이용한 예이다.

    SleepEx(10, TRUE);

}

 

※ 스레드를 얼러터블 상태로 변경할 수 있는 함수

DWORD SleepEx ( DWORD dwMilliseconds, BOOL bAlertable);

DWORD WaitForSingleObjectEx (...);

DWORD WaitForMultipleObjectsEx(...);

BOOL SignalObjectAndWait(...);

BOOL GetQueuedCompletionStatusEx(...);

DWORD MsgWaitForMultipleObjectsEx(...);

 

'개발지식창고 > Serial통신' 카테고리의 다른 글

OVERLAPPED  (0) 2011.12.19
Overlapped I/O (2)  (0) 2011.12.19
Overlapped I/O (1)  (0) 2011.12.19
Serial 통신 Cycle  (0) 2011.11.30
Posted by 모과이IT
,