SlideShare ist ein Scribd-Unternehmen logo
1 von 39
동기?! 비동기?!

• 동기(Synchronous) : 동시 발생하는

• 비동기(Asynchronous) : 동시에 존재하지 않는
장치란 ?!
• 정의 : 통신 가능한 어떤 것

• 종류 : 파일, 직렬포트, 메일슬롯, 소켓, etc... (p.388 표 10-1)

• 특성 : 일부 장치를 제외하고는 인터페이스가 같다.
    CreateMailSlot(), CreateNamedPipe()

HANDLE hHandle = CreateFile(...                    생성

SetCommConfig (HANDLE hCommDev, ...
SetMailslotInfo (HANDLE hMailslot, ...             이용

CloseHandle(HANDLE hObject)                        종료

 !! 단 장치가 Socket이였다면 Closesocket(SOCKET s)
HANDLE CreateFile (
      PCTSTR pszName,
      DWORD dwDesireAccess,
      DWORD dwShareMode,
      PSECURITY_ATTRIBUTES psa,
      DWORD dwCreationDisposition,
      DWORD dwFlagsAndAttributes,
      HANDLE hFileTemplate);


•   pszName : 특정 장치의 인스턴스 / 장치의 타입을 구분
•   dwDesireAccess : 장치와 데이터 주고받길 원하는 범위
•   dwShareMode : 장치의 공유특성
•   Psa : 보안 설정
•   dwCreationDisposition : 파일을 여는 방법
•   dwFlagsAndAttributes : 세부적 통신 Flag / 파일의 특성
•   hFileTemplate : 이미 열린 파일에 대한 핸들 or NULL

!! 파일이 아닌 다른 장치에 대해서는 반드시 OPEN_EXISTING

                                         (p.391 ~ 398)
장치 이용하기
• 파일 크기 얻기

• 파일 포인터 위치 지정

• 파일의 끝 설정


BOOL GetFileSize (hFile, ...);                    논리적인 크기 반환
DWORD GetCompressedFileSize (pszFileName, ...);
                                                  물리적인 크기 반환

ReadFile (hFile, ...);                 64bit 오프셋
SetFilePointEx (hFile, ... );          동기적인 I/O를 수행할 위치



SetEndOfFile(hFile, ...);              커널오브젝트의 파일
                                       포인터 변경
동기 장치 I/O
• 동기 장치 I/O 수행

• 동기 장치 I/O 취소 (전적으로 드라이버에 달려있다.)


BOOL ReadFile (
HANDLE            hFile,
PVOID             pvBuffer,
DWORD nNumByteToRead,
PDWORD            pdwNumBytes,
OVERLAPPED* pOverlapped);


BOOL CancelSynchronousIo (HANDLE hThread);
컴퓨터가 수행하는 다른 작업들에 비해 장치 I/O는 상대적으로 가
장 느리고, 예측할 수 없는 작업 중 하나다.
비동기 I/O 요청은 고성능의 확장성 있는 애플리케이션을 개발하
기 위하여 설계 되었다.
1. 실제로 I/O 작업을 수행할 장치의 디바이스 드라이버로 전달
2. 디바이스 드라이버가 장치로 부터 응답 대기
3. 애플리케이션은 I/O 완료될때까지 다른 작업 수행

BOOL ReadFile (
HANDLE            hFile,
PVOID             pvBuffer,
DWORD nNumByteToRead,
PDWORD            pdwNumBytes,
OVERLAPPED* pOverlapped); FILE_FLAG_OVERLAPPED
typedef struct _OVERLAPPED {
       DWORD Internal;
       DWORD InternalHigh;
       DWORD Offset;
       DWORD OffsetHigh;
       HANDLE hEvent;
} OVERLAPPED, *LPOVERLAPPED;


• Internal : 처리된 I/O의 에러 코드를 담는데 사용한다. 비동기 I/O 요청
  을 시도하면 디바이스 드라이버는 Internal 멤버 값을
  STATUS_PENDING으로 설정하여 아직 작업이 완료되지 않았으며
  어떠한 에러도 발생하지 않았음을 나타낸다.

• InternalHigh : 비동기 I/O 작업이 완료되면 이 멤버는 실제로 송수신된
  바이트 수를 저장하게 된다.
• Offset : 이 인자와 아래 OffsetHigh를 통해 파일 내에서 I/O 작업을 시
  작할 위치를 64비트 오프셋 값으로 지정할 수 있다. 동일한 파일 커널
  오브젝트에 대해 여러 번의 비동기 I/O 요청 시에는 반드시
  OVERLAPPED 구조체 내에 I/O 작업을 시작할 위치를 지정해야 한다.



• OffsetHigh : 위의 Offset과 같은 역할을 하며 32비트 상위 파일의 오
  프셍을 나타낸다.


• hEvent : 이 멤버는 I/O 완료 통지를 수신하는 네 가지 방법 중 하나의
  방법에서 사용된다. 얼러터블 I/O 통지 방법을 사용하는 경우에는 사
  용자 임의로 이 멤버를 사용할 수도 있다.
• 비동기 I/O 요청이 완료되면 I/O 요청 시 사용했던
     OVERLAPPED 구조체의 주소를 돌려주게 된다. 그러므로 이
     구조체에 장치 핸들이나 유용한 컨텍스트 정보를 저장할 만한
     멤버를 포함시켜서 작성하기도 한다.

Enum IOType
{
        OP_RECV,
        OP_SEND
}
class OVERLAPPEDEX : public OVERLAPPED
{
        IOType       m_eIOType;
        SOCKET       m_hSocket;
};
비동기 장치 I/O 사용 시 주의점


1. 디바이스 드라이버는 비동기 I/O요청을 항상 선입 선출로 처리 안함


2. 에러 확인을 수행하는 적당한 방법에 대해 알고 있어야 한다.
  1. 비동기 요청에도 시스템에 의해 동기적으로 처리될 때 있다.
  2. Read / Write File은 I/O 요청이 동기적으로 수행되는 경우 0이 아
    닌 값을 반환
  3. I/O 요청이 비동기적으로 수행되는 경우나 에러 발생시 FALSE
    반환, 고로 GetLastError (ERROR_IO_PENDING)


3. 데이터 버퍼와 OVERLAPPED 구조체는 I/O 요청이 완료될 때까지
  옮겨지거나 삭제되지 않아야 한다.
요청된 장치 I/O의 취소


•   CancelIo 함수 호출
    •   이 함수를 호출한 스레드가 삽입한 모든 I/O 요청 취소


•   장치에 대한 핸들 닫기
    •   어떤 스레드가 I/O 요청을 삽입한지 고려하지 않고 모든 I/O 요청 취소


•   핸들이 I/O 컴플레이션 포트와 연계되어 있는 경우를 제외하면, 스레드가
    종료될 때 종료된 스레드가 삽입하였던 모든 I/O 요청이 취소


•   특정 장치에 대해 하나의 I/O 요청만 취소할 때
    •   CancelIoEx 함수 호출
완료 통지 방법?


•   비동기 호출은 언제 완료될 지 알 수 없기때문에 I/O 작업이 완료되면 완료
    된 사실을 통지해 주어야 한다.
완료 통지 방법?

방법                  요약

디바이스 커널 오브젝트 시그널링   •   단일의 장치에 대해 다수의 I/O 요청 적합하지
                        않다.
                    •   특정 스레드가 I/O 요청을 삽입하고 다른 스레
                        드가 완료 통지를 수신할 수 있다.
이벤트 커널 오브젝트의 시그널링   •   단일의 장치에 대해 다수의 I/O 요청을 수행할
                        수 있다.
                    •   특정 스레드가 I/O 요청을 삽입하고 다른 스레
                        드가 완료 통지를 수신할 수 있다.
얼러터블 I/O 사용         •   단일의 장치에 대해 다수의 I/O 요청을 수행할
                        수 있다.
                    •   항상 I/O 요청을 삽입한 스레드가 완료 통지를
                        수신한다.
I/O 컴플리션 포트 사용      •   단일의 장치에 대해 다수의 I/O 요청을 수행할
                        수 있다.
                    •   특정 스레드가 I/O 요청을 삽입하고 다른 스레
                        드가 완료 통지를 수신할 수 있다.
                    •   이 방법이 가장 확장성이 뛰어나고 유연성이 있
                        다.
디바이스 커널 오브젝트의 시그널링


 •   디바이스 커널 오브젝트의 시그널과 논시그널 상태를 이용.

HANDLE hFile = CreateFile(..., FILE_FLAG_OVERLAPPED, ...)
BYTE bBuffer[100];
OVERLAPPED o = { 0 };
o.Offset = 345;

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

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

If (bReadDone) {
...
}
디바이스 커널 오브젝트의 시그널링


•   비동기 I/O를 위해 디바이스를 열 때 반드시 FILE_FLAG_OVERLAPPED

•   OVERLAPPED 구조체의 Offset, OffsetHigh, hEvent 초기화

•   bReadDone을 확인후 동기적으로 수행되었는지 확인하고 동기적이 아니
    라면 비동기적으로 I/O 작업이 요청되었는지 확인

•   읽기 작업 완료 시 bBuffer에는 읽은 데이터가, OVERLAPPED 구조체의
    Internal 멤버에는 Error코드가, InternalHigh 멤버에는 읽은 데이터의 크기
    가 각각 저장된다.
디바이스 커널 오브젝트의 시그널링의 문제 ?

HANDLE hFile = CreateFile(..., FILE_FLAG_OVERLAPPED, ...)
BYTE bReadBuffer[100];
OVERLAPPED oRead = { 0 };

ReadFile(hFile, bReadBuffer, 100, NULL, &oRead);

BYTE bWriteBuffer[10] = {0, 1, 2, 3, ... };
OVERLAPPED oWrite = { 0 };
oWrite.Offset = 10;

WirteFile(hFile, bWriteBuffer, _countof(bWriteBuffer), NULL, &oWrite);

...

WaitForSingleObject(hFile, INFINITE)

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


HANDLE hHandle = CreateFile(..., FILE_FLAG_OVERLAPPED, ...)
BYTE bReadBuffer[100];
OVERLAPPED oRead = { 0 };
oRead.hEvent = CreateEvent(...);

ReadFile(hFile, bReadBuffer, 100, NULL, &oRead);

BYTE bWriteBuffer[10] = {0, 1, 2, 3, ... };
OVERLAPPED oWrite = { 0 };
oWirte.hEvent = CreateEvent(...);

WirteFile(hFile, bWriteBuffer, _countof(bWriteBuffer), NULL, &oWrite);
이벤트 커널 오브젝트의 시그널링


HANDLE h[2];
h[0] = oRead.hEvent;
h[1] = oWrite.hEvent;

DWORD dw = WaitForMultipleObjects(2, h, FALSE, INFINITE);
Switch (dw – WAIT_OBJECT_0) {
         case 0:        // 읽기 작업 완료
                 break;

        case 1:            // 쓰기 작업 완료
                  break;
}


 GetOverlappedResult(...)
     하지만 현재는 Internal과 InternalHigh이 문서화
얼러터블 I/O

 APC(Asynchronous Procedure Call)
    스레드가 생성되면 APC 큐라 불리는 큐가 하나씩 생성
    ReadFileEX / WriteFileEX

  BOOL ReadFileEx (
  HANDLE          hFile,
  PVOID           pvBuffer,
  DWORD nNumByteToRead,
  OVERLAPPED* pOverlapped,
  LPOVERLAPPED_COMPLETION_ROUTINE pfnRoutine);

     VOID WINAPI CompletionRoutine (
            DWORD dwError,
            DWORD pwNumBytes,
            OVERLAPPED* po);
얼러터블 I/O

hFile = CreateFile(..., FILE_FLAG_OVERLAPPED, ...);


ReadFileEx(hFile, ...);
WriteFileEx(hFile, ...);
ReadFileEx(hFile, ...);


SomeFunc();


Write I/O     Read I/O     Read I/O




 스레드를 인터럽트 가능한 상태가 되었음을 알려줘야한다.
      즉, 스레드를 얼러터블 상태로 변경
얼러터블 I/O

 얼러터블 상태로 변경할 수 있는 함수
•   SleepEx / WaitForSingleObjectEx / WaitForMultipleObjectsEx /
    SignalObjectAndWait / GetQueuedCompletionStatusEx /
    MsgWaitForMultipleObjectsEx



 얼러터블 I/O의 장단점
•   장점
     •   비동기 호출을 가능하게 만들어준다..ㅠ.ㅠ
     •   단일 스레드라서 동기화 처리를 할 필요가 없다. ㅠ.ㅠ
•   단점
     •   콜백함수
     •   쓰레딩 문제
I/O 컴플리션 포트


•    컨커런트 모델
      •   컨커런트 모델을 사용하는 서비스 애플리케이션을 윈도우에서 구현
          하였을 때 성능이 기대만큼 나오지 않자 개선해서 나온 결과로 태어난
          것이 바로 I/O 컴플리션 포트 커널 오브젝트이다

•    I/O 컴플리션 포트 생성

    HANDLE CreateIoCompletionPort(
           HANDLE hFile,
           HANDLE hExistingCompletionPort,
           ULONG_PTR CompletionKey,
           DWORD dwNumberOfConcurrentThreads);
I/O 컴플리션 포트

    HANDLE CreateNewCompletionPort (DWORD dwThreads)
    {
              return CreateIoCompletionPort(
                      INVALID_HANDLE_VALUE, NULL, 0,
                      dwThreads);
    |

•       dwThreads
         •   동일 시간에 동시에 수행할 수 있는 스레드의 최대 개수
         •   보통은 CPU 개수만큼을 입력
I/O 컴플리션 포트

•    I/O 컴플리션 포트 연계

    HANDLE CreateIoCompletionPort(
           HANDLE hFile,
           HANDLE hExistingCompletionPort,
           ULONG_PTR CompletionKey,
           DWORD dwNumberOfConcurrentThreads);


•    hFile : 장치에 대한 핸들 (파일, 소켓, 메일슬롯, 파이프등)
•    hExistingCompletionPort : 생성해 둔 I/O 컴플리션 포트 핸들
•    CompletionKey : 컴플리션 키 (사용자가 임의로 결정할 수 있다.)
I/O 컴플리션 포트

•       I/O 컴플리션 포트 연계

    BOOL AssociateDeviceWithCompletionPort(
            HANDLE hDevice,
            HANDLE hExistingCompletionPort,
            ULONG_PTR CompletionKey,) {


            HANDLE h = CreateIoCompletionPort(hDevice,
            hCompletionPort, dwCompletionKey, 0);
            return (h == hCompletionPort);
    }
I/O 컴플리션 포트

              • 장치 리스트


              • I/O 컴플리션 큐



              • 대기 스레드 큐



              • 릴리즈 스레드 리스트



              • 일시 정지 스레드 리스트
I/O 컴플리션 포트

커널 모드


      Device List       I/O Request List   I/O Completion Queue




유저 모드

                           WSARecv()
                          WSASend()        GetQueuedCompletionS
 CreateCompletionPort
                          ReadFileEX()            tatus()
                              …
I/O 컴플리션 포트를 이용한 아키텍쳐 설계

•    클라이언트의 요청을 처리하는 스레드 풀
      •   풀 내에 몇 개의 스레드를 생성해 두는 것이 좋은가? (다음발표자분)
•    완료 통지가 전달 되었을 때 처리할 수 있도록 스레드를 대기 상태로!!


    BOOL GetQueuedCompletionStatus(
           HANDLE hCompletionPort,
           PDWORD pdwNumberOfBytesTransferred,
           PULONG_PTR pCompletionKey,
           OVERLAPPED** ppOverlapped,
           DWORD dwMilliseconds);
I/O 컴플리션 포트를 이용한 아키텍쳐 설계

•   대기 스레드 큐
    •   후입선출(LIFO) 방식으로 스레드를 깨운다.
•   릴리즈 스레드 리스트
    •   I/O 컴플리션 포트가 대기 스레드 큐에 있는 스레드를 깨우는 경우
    •   일시 정지되었던 스레드가 다시 깨어났을 경우
•   일시 정지 스레드 리스트
    •   수행 중이던 스레드가 스레드를 정지시키는 함수를 호출
    •   정지 중이던 스레드가 깨어나면 릴리즈 스레드 리스트로 삽입
I/O 컴플리션 포트의 스레드 풀 관리방법

•   I/O 컴플리션 포트 생성할 때 지정한 스레드 개수 이상을 초과할 수 없다
•   근데 왜?! 이보다 많은 스레드를 풀로 관리해야 하는가?
    •   릴리즈 스레드 리스트
    •   대기 스레드 리스트


 I/O 컴플리션 사용 목적
     CPU가 계속해서 작업을 수행하도록 상태를 유지하는 것
Windows via C/C++ Chapter 10
Windows via C/C++ Chapter 10

Weitere ähnliche Inhalte

Was ist angesagt?

Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택JinTaek Seo
 
Windows reversing study_basic_5
Windows reversing study_basic_5Windows reversing study_basic_5
Windows reversing study_basic_5Jinkyoung Kim
 
파이썬 2와 유니코드
파이썬 2와 유니코드파이썬 2와 유니코드
파이썬 2와 유니코드성주 이
 
[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11흥배 최
 
Web hacking introduction
Web hacking introductionWeb hacking introduction
Web hacking introductionJinkyoung Kim
 
Javascript 교육자료 pdf
Javascript 교육자료 pdfJavascript 교육자료 pdf
Javascript 교육자료 pdfHyosang Hong
 
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)Sang Don Kim
 
C++ 11 에 대해서 쉽게 알아봅시다 1부
C++ 11 에 대해서 쉽게 알아봅시다 1부C++ 11 에 대해서 쉽게 알아봅시다 1부
C++ 11 에 대해서 쉽게 알아봅시다 1부Gwangwhi Mah
 
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013Esun Kim
 
Near field communication
Near field communicationNear field communication
Near field communicationDH Y.
 
Cpp 0x kimRyungee
Cpp 0x kimRyungeeCpp 0x kimRyungee
Cpp 0x kimRyungeescor7910
 
[2013 CodeEngn Conference 08] manGoo - Windows 8 Exploit
[2013 CodeEngn Conference 08] manGoo - Windows 8 Exploit[2013 CodeEngn Conference 08] manGoo - Windows 8 Exploit
[2013 CodeEngn Conference 08] manGoo - Windows 8 ExploitGangSeok Lee
 
Windows reversing study_basic_1
Windows reversing study_basic_1Windows reversing study_basic_1
Windows reversing study_basic_1Jinkyoung Kim
 
[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드
[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드
[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드GangSeok Lee
 
GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)
GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)
GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)Kyoungchan Lee
 
Pwnable study basic_3
Pwnable study basic_3Pwnable study basic_3
Pwnable study basic_3Jinkyoung Kim
 
[2008 CodeEngn Conference 02] seaofglass - Immunity Debugger 활용과 플러그인 제작
[2008 CodeEngn Conference 02] seaofglass - Immunity Debugger 활용과 플러그인 제작[2008 CodeEngn Conference 02] seaofglass - Immunity Debugger 활용과 플러그인 제작
[2008 CodeEngn Conference 02] seaofglass - Immunity Debugger 활용과 플러그인 제작GangSeok Lee
 
Windows reversing study_basic_2
Windows reversing study_basic_2Windows reversing study_basic_2
Windows reversing study_basic_2Jinkyoung Kim
 

Was ist angesagt? (20)

Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택
 
Windows reversing study_basic_5
Windows reversing study_basic_5Windows reversing study_basic_5
Windows reversing study_basic_5
 
파이썬 2와 유니코드
파이썬 2와 유니코드파이썬 2와 유니코드
파이썬 2와 유니코드
 
[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11
 
Web hacking introduction
Web hacking introductionWeb hacking introduction
Web hacking introduction
 
Javascript 교육자료 pdf
Javascript 교육자료 pdfJavascript 교육자료 pdf
Javascript 교육자료 pdf
 
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
 
C++ 11 에 대해서 쉽게 알아봅시다 1부
C++ 11 에 대해서 쉽게 알아봅시다 1부C++ 11 에 대해서 쉽게 알아봅시다 1부
C++ 11 에 대해서 쉽게 알아봅시다 1부
 
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
 
Near field communication
Near field communicationNear field communication
Near field communication
 
Cpp 0x kimRyungee
Cpp 0x kimRyungeeCpp 0x kimRyungee
Cpp 0x kimRyungee
 
[2013 CodeEngn Conference 08] manGoo - Windows 8 Exploit
[2013 CodeEngn Conference 08] manGoo - Windows 8 Exploit[2013 CodeEngn Conference 08] manGoo - Windows 8 Exploit
[2013 CodeEngn Conference 08] manGoo - Windows 8 Exploit
 
System+os study 1
System+os study 1System+os study 1
System+os study 1
 
Windows reversing study_basic_1
Windows reversing study_basic_1Windows reversing study_basic_1
Windows reversing study_basic_1
 
8 swift 중첩함수
8 swift 중첩함수8 swift 중첩함수
8 swift 중첩함수
 
[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드
[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드
[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드
 
GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)
GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)
GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)
 
Pwnable study basic_3
Pwnable study basic_3Pwnable study basic_3
Pwnable study basic_3
 
[2008 CodeEngn Conference 02] seaofglass - Immunity Debugger 활용과 플러그인 제작
[2008 CodeEngn Conference 02] seaofglass - Immunity Debugger 활용과 플러그인 제작[2008 CodeEngn Conference 02] seaofglass - Immunity Debugger 활용과 플러그인 제작
[2008 CodeEngn Conference 02] seaofglass - Immunity Debugger 활용과 플러그인 제작
 
Windows reversing study_basic_2
Windows reversing study_basic_2Windows reversing study_basic_2
Windows reversing study_basic_2
 

Ähnlich wie Windows via C/C++ Chapter 10

10 동기및비동기장치io
10 동기및비동기장치io10 동기및비동기장치io
10 동기및비동기장치iossuser3fb17c
 
11장 윈도우 스레드 풀
11장 윈도우 스레드 풀11장 윈도우 스레드 풀
11장 윈도우 스레드 풀홍준 김
 
11장 윈도우 스레드 풀 + 12장 파이버
11장 윈도우 스레드 풀 + 12장 파이버11장 윈도우 스레드 풀 + 12장 파이버
11장 윈도우 스레드 풀 + 12장 파이버홍준 김
 
Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표Kwen Won Lee
 
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing SystemGCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System상현 조
 
windows via c++ Ch 5. Job
windows via c++ Ch 5. Jobwindows via c++ Ch 5. Job
windows via c++ Ch 5. JobHyosung Jeon
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해Nam Hyeonuk
 
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계Sungkyun Kim
 
NodeJs로 디바이스 통신하기
NodeJs로 디바이스 통신하기NodeJs로 디바이스 통신하기
NodeJs로 디바이스 통신하기TaeYoung Kim
 
Tizen main loop 이해
Tizen main loop 이해Tizen main loop 이해
Tizen main loop 이해Hermet Park
 
I phone 2 release
I phone 2 releaseI phone 2 release
I phone 2 releaseJaehyeuk Oh
 
Do IoT Yourself! - 사물 간의 연결을 위한 Open API
Do IoT Yourself! - 사물 간의 연결을 위한 Open APIDo IoT Yourself! - 사물 간의 연결을 위한 Open API
Do IoT Yourself! - 사물 간의 연결을 위한 Open APIHyunghun Cho
 
NODE.JS 글로벌 기업 적용 사례 그리고, real-time 어플리케이션 개발하기
NODE.JS 글로벌 기업 적용 사례  그리고, real-time 어플리케이션 개발하기NODE.JS 글로벌 기업 적용 사례  그리고, real-time 어플리케이션 개발하기
NODE.JS 글로벌 기업 적용 사례 그리고, real-time 어플리케이션 개발하기John Kim
 
eclipse에서 intelliJ IDEA로
eclipse에서 intelliJ IDEA로eclipse에서 intelliJ IDEA로
eclipse에서 intelliJ IDEA로Juntai Park
 
I os push: 세상에서 가장 간단한 날씨, 대기환경 엡
I os push:  세상에서 가장 간단한  날씨, 대기환경 엡I os push:  세상에서 가장 간단한  날씨, 대기환경 엡
I os push: 세상에서 가장 간단한 날씨, 대기환경 엡HannaSungKim
 
Open vSwitch의 Vendor Extension 구현
Open vSwitch의 Vendor Extension 구현Open vSwitch의 Vendor Extension 구현
Open vSwitch의 Vendor Extension 구현Seung-Hoon Baek
 

Ähnlich wie Windows via C/C++ Chapter 10 (20)

10 동기및비동기장치io
10 동기및비동기장치io10 동기및비동기장치io
10 동기및비동기장치io
 
11장 윈도우 스레드 풀
11장 윈도우 스레드 풀11장 윈도우 스레드 풀
11장 윈도우 스레드 풀
 
11장 윈도우 스레드 풀 + 12장 파이버
11장 윈도우 스레드 풀 + 12장 파이버11장 윈도우 스레드 풀 + 12장 파이버
11장 윈도우 스레드 풀 + 12장 파이버
 
Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표
 
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing SystemGCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
 
windows via c++ Ch 5. Job
windows via c++ Ch 5. Jobwindows via c++ Ch 5. Job
windows via c++ Ch 5. Job
 
Device driver
Device driverDevice driver
Device driver
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해
 
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계
 
NodeJs로 디바이스 통신하기
NodeJs로 디바이스 통신하기NodeJs로 디바이스 통신하기
NodeJs로 디바이스 통신하기
 
Tizen main loop 이해
Tizen main loop 이해Tizen main loop 이해
Tizen main loop 이해
 
I phone 2 release
I phone 2 releaseI phone 2 release
I phone 2 release
 
Do IoT Yourself! - 사물 간의 연결을 위한 Open API
Do IoT Yourself! - 사물 간의 연결을 위한 Open APIDo IoT Yourself! - 사물 간의 연결을 위한 Open API
Do IoT Yourself! - 사물 간의 연결을 위한 Open API
 
NODE.JS 글로벌 기업 적용 사례 그리고, real-time 어플리케이션 개발하기
NODE.JS 글로벌 기업 적용 사례  그리고, real-time 어플리케이션 개발하기NODE.JS 글로벌 기업 적용 사례  그리고, real-time 어플리케이션 개발하기
NODE.JS 글로벌 기업 적용 사례 그리고, real-time 어플리케이션 개발하기
 
eclipse에서 intelliJ IDEA로
eclipse에서 intelliJ IDEA로eclipse에서 intelliJ IDEA로
eclipse에서 intelliJ IDEA로
 
I os push: 세상에서 가장 간단한 날씨, 대기환경 엡
I os push:  세상에서 가장 간단한  날씨, 대기환경 엡I os push:  세상에서 가장 간단한  날씨, 대기환경 엡
I os push: 세상에서 가장 간단한 날씨, 대기환경 엡
 
Meteor IoT
Meteor IoTMeteor IoT
Meteor IoT
 
Init to systemd
Init to systemdInit to systemd
Init to systemd
 
OpenStack Swift Debugging
OpenStack Swift DebuggingOpenStack Swift Debugging
OpenStack Swift Debugging
 
Open vSwitch의 Vendor Extension 구현
Open vSwitch의 Vendor Extension 구현Open vSwitch의 Vendor Extension 구현
Open vSwitch의 Vendor Extension 구현
 

Windows via C/C++ Chapter 10

  • 1.
  • 2.
  • 3. 동기?! 비동기?! • 동기(Synchronous) : 동시 발생하는 • 비동기(Asynchronous) : 동시에 존재하지 않는
  • 4.
  • 5. 장치란 ?! • 정의 : 통신 가능한 어떤 것 • 종류 : 파일, 직렬포트, 메일슬롯, 소켓, etc... (p.388 표 10-1) • 특성 : 일부 장치를 제외하고는 인터페이스가 같다.  CreateMailSlot(), CreateNamedPipe() HANDLE hHandle = CreateFile(... 생성 SetCommConfig (HANDLE hCommDev, ... SetMailslotInfo (HANDLE hMailslot, ... 이용 CloseHandle(HANDLE hObject) 종료 !! 단 장치가 Socket이였다면 Closesocket(SOCKET s)
  • 6. HANDLE CreateFile ( PCTSTR pszName, DWORD dwDesireAccess, DWORD dwShareMode, PSECURITY_ATTRIBUTES psa, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hFileTemplate); • pszName : 특정 장치의 인스턴스 / 장치의 타입을 구분 • dwDesireAccess : 장치와 데이터 주고받길 원하는 범위 • dwShareMode : 장치의 공유특성 • Psa : 보안 설정 • dwCreationDisposition : 파일을 여는 방법 • dwFlagsAndAttributes : 세부적 통신 Flag / 파일의 특성 • hFileTemplate : 이미 열린 파일에 대한 핸들 or NULL !! 파일이 아닌 다른 장치에 대해서는 반드시 OPEN_EXISTING (p.391 ~ 398)
  • 7.
  • 8. 장치 이용하기 • 파일 크기 얻기 • 파일 포인터 위치 지정 • 파일의 끝 설정 BOOL GetFileSize (hFile, ...); 논리적인 크기 반환 DWORD GetCompressedFileSize (pszFileName, ...); 물리적인 크기 반환 ReadFile (hFile, ...); 64bit 오프셋 SetFilePointEx (hFile, ... ); 동기적인 I/O를 수행할 위치 SetEndOfFile(hFile, ...); 커널오브젝트의 파일 포인터 변경
  • 9.
  • 10. 동기 장치 I/O • 동기 장치 I/O 수행 • 동기 장치 I/O 취소 (전적으로 드라이버에 달려있다.) BOOL ReadFile ( HANDLE hFile, PVOID pvBuffer, DWORD nNumByteToRead, PDWORD pdwNumBytes, OVERLAPPED* pOverlapped); BOOL CancelSynchronousIo (HANDLE hThread);
  • 11.
  • 12. 컴퓨터가 수행하는 다른 작업들에 비해 장치 I/O는 상대적으로 가 장 느리고, 예측할 수 없는 작업 중 하나다. 비동기 I/O 요청은 고성능의 확장성 있는 애플리케이션을 개발하 기 위하여 설계 되었다. 1. 실제로 I/O 작업을 수행할 장치의 디바이스 드라이버로 전달 2. 디바이스 드라이버가 장치로 부터 응답 대기 3. 애플리케이션은 I/O 완료될때까지 다른 작업 수행 BOOL ReadFile ( HANDLE hFile, PVOID pvBuffer, DWORD nNumByteToRead, PDWORD pdwNumBytes, OVERLAPPED* pOverlapped); FILE_FLAG_OVERLAPPED
  • 13. typedef struct _OVERLAPPED { DWORD Internal; DWORD InternalHigh; DWORD Offset; DWORD OffsetHigh; HANDLE hEvent; } OVERLAPPED, *LPOVERLAPPED; • Internal : 처리된 I/O의 에러 코드를 담는데 사용한다. 비동기 I/O 요청 을 시도하면 디바이스 드라이버는 Internal 멤버 값을 STATUS_PENDING으로 설정하여 아직 작업이 완료되지 않았으며 어떠한 에러도 발생하지 않았음을 나타낸다. • InternalHigh : 비동기 I/O 작업이 완료되면 이 멤버는 실제로 송수신된 바이트 수를 저장하게 된다.
  • 14. • Offset : 이 인자와 아래 OffsetHigh를 통해 파일 내에서 I/O 작업을 시 작할 위치를 64비트 오프셋 값으로 지정할 수 있다. 동일한 파일 커널 오브젝트에 대해 여러 번의 비동기 I/O 요청 시에는 반드시 OVERLAPPED 구조체 내에 I/O 작업을 시작할 위치를 지정해야 한다. • OffsetHigh : 위의 Offset과 같은 역할을 하며 32비트 상위 파일의 오 프셍을 나타낸다. • hEvent : 이 멤버는 I/O 완료 통지를 수신하는 네 가지 방법 중 하나의 방법에서 사용된다. 얼러터블 I/O 통지 방법을 사용하는 경우에는 사 용자 임의로 이 멤버를 사용할 수도 있다.
  • 15. • 비동기 I/O 요청이 완료되면 I/O 요청 시 사용했던 OVERLAPPED 구조체의 주소를 돌려주게 된다. 그러므로 이 구조체에 장치 핸들이나 유용한 컨텍스트 정보를 저장할 만한 멤버를 포함시켜서 작성하기도 한다. Enum IOType { OP_RECV, OP_SEND } class OVERLAPPEDEX : public OVERLAPPED { IOType m_eIOType; SOCKET m_hSocket; };
  • 16. 비동기 장치 I/O 사용 시 주의점 1. 디바이스 드라이버는 비동기 I/O요청을 항상 선입 선출로 처리 안함 2. 에러 확인을 수행하는 적당한 방법에 대해 알고 있어야 한다. 1. 비동기 요청에도 시스템에 의해 동기적으로 처리될 때 있다. 2. Read / Write File은 I/O 요청이 동기적으로 수행되는 경우 0이 아 닌 값을 반환 3. I/O 요청이 비동기적으로 수행되는 경우나 에러 발생시 FALSE 반환, 고로 GetLastError (ERROR_IO_PENDING) 3. 데이터 버퍼와 OVERLAPPED 구조체는 I/O 요청이 완료될 때까지 옮겨지거나 삭제되지 않아야 한다.
  • 17. 요청된 장치 I/O의 취소 • CancelIo 함수 호출 • 이 함수를 호출한 스레드가 삽입한 모든 I/O 요청 취소 • 장치에 대한 핸들 닫기 • 어떤 스레드가 I/O 요청을 삽입한지 고려하지 않고 모든 I/O 요청 취소 • 핸들이 I/O 컴플레이션 포트와 연계되어 있는 경우를 제외하면, 스레드가 종료될 때 종료된 스레드가 삽입하였던 모든 I/O 요청이 취소 • 특정 장치에 대해 하나의 I/O 요청만 취소할 때 • CancelIoEx 함수 호출
  • 18.
  • 19. 완료 통지 방법? • 비동기 호출은 언제 완료될 지 알 수 없기때문에 I/O 작업이 완료되면 완료 된 사실을 통지해 주어야 한다.
  • 20. 완료 통지 방법? 방법 요약 디바이스 커널 오브젝트 시그널링 • 단일의 장치에 대해 다수의 I/O 요청 적합하지 않다. • 특정 스레드가 I/O 요청을 삽입하고 다른 스레 드가 완료 통지를 수신할 수 있다. 이벤트 커널 오브젝트의 시그널링 • 단일의 장치에 대해 다수의 I/O 요청을 수행할 수 있다. • 특정 스레드가 I/O 요청을 삽입하고 다른 스레 드가 완료 통지를 수신할 수 있다. 얼러터블 I/O 사용 • 단일의 장치에 대해 다수의 I/O 요청을 수행할 수 있다. • 항상 I/O 요청을 삽입한 스레드가 완료 통지를 수신한다. I/O 컴플리션 포트 사용 • 단일의 장치에 대해 다수의 I/O 요청을 수행할 수 있다. • 특정 스레드가 I/O 요청을 삽입하고 다른 스레 드가 완료 통지를 수신할 수 있다. • 이 방법이 가장 확장성이 뛰어나고 유연성이 있 다.
  • 21. 디바이스 커널 오브젝트의 시그널링 • 디바이스 커널 오브젝트의 시그널과 논시그널 상태를 이용. HANDLE hFile = CreateFile(..., FILE_FLAG_OVERLAPPED, ...) BYTE bBuffer[100]; OVERLAPPED o = { 0 }; o.Offset = 345; BOOL bReadDone = ReadFile(hFile, bBuffer, 100, NULL, &o); DWORD dwError = GetLastError(); If (!bReadDone && (dwError == ERROR_IO_PENDING)) { WaitForSingleObject(hFile, INFINITE); bReadDone = TRUE; } If (bReadDone) { ... }
  • 22. 디바이스 커널 오브젝트의 시그널링 • 비동기 I/O를 위해 디바이스를 열 때 반드시 FILE_FLAG_OVERLAPPED • OVERLAPPED 구조체의 Offset, OffsetHigh, hEvent 초기화 • bReadDone을 확인후 동기적으로 수행되었는지 확인하고 동기적이 아니 라면 비동기적으로 I/O 작업이 요청되었는지 확인 • 읽기 작업 완료 시 bBuffer에는 읽은 데이터가, OVERLAPPED 구조체의 Internal 멤버에는 Error코드가, InternalHigh 멤버에는 읽은 데이터의 크기 가 각각 저장된다.
  • 23. 디바이스 커널 오브젝트의 시그널링의 문제 ? HANDLE hFile = CreateFile(..., FILE_FLAG_OVERLAPPED, ...) BYTE bReadBuffer[100]; OVERLAPPED oRead = { 0 }; ReadFile(hFile, bReadBuffer, 100, NULL, &oRead); BYTE bWriteBuffer[10] = {0, 1, 2, 3, ... }; OVERLAPPED oWrite = { 0 }; oWrite.Offset = 10; WirteFile(hFile, bWriteBuffer, _countof(bWriteBuffer), NULL, &oWrite); ... WaitForSingleObject(hFile, INFINITE) // ???
  • 24. 이벤트 커널 오브젝트의 시그널링 HANDLE hHandle = CreateFile(..., FILE_FLAG_OVERLAPPED, ...) BYTE bReadBuffer[100]; OVERLAPPED oRead = { 0 }; oRead.hEvent = CreateEvent(...); ReadFile(hFile, bReadBuffer, 100, NULL, &oRead); BYTE bWriteBuffer[10] = {0, 1, 2, 3, ... }; OVERLAPPED oWrite = { 0 }; oWirte.hEvent = CreateEvent(...); WirteFile(hFile, bWriteBuffer, _countof(bWriteBuffer), NULL, &oWrite);
  • 25. 이벤트 커널 오브젝트의 시그널링 HANDLE h[2]; h[0] = oRead.hEvent; h[1] = oWrite.hEvent; DWORD dw = WaitForMultipleObjects(2, h, FALSE, INFINITE); Switch (dw – WAIT_OBJECT_0) { case 0: // 읽기 작업 완료 break; case 1: // 쓰기 작업 완료 break; }  GetOverlappedResult(...)  하지만 현재는 Internal과 InternalHigh이 문서화
  • 26. 얼러터블 I/O  APC(Asynchronous Procedure Call)  스레드가 생성되면 APC 큐라 불리는 큐가 하나씩 생성  ReadFileEX / WriteFileEX BOOL ReadFileEx ( HANDLE hFile, PVOID pvBuffer, DWORD nNumByteToRead, OVERLAPPED* pOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE pfnRoutine); VOID WINAPI CompletionRoutine ( DWORD dwError, DWORD pwNumBytes, OVERLAPPED* po);
  • 27. 얼러터블 I/O hFile = CreateFile(..., FILE_FLAG_OVERLAPPED, ...); ReadFileEx(hFile, ...); WriteFileEx(hFile, ...); ReadFileEx(hFile, ...); SomeFunc(); Write I/O Read I/O Read I/O  스레드를 인터럽트 가능한 상태가 되었음을 알려줘야한다.  즉, 스레드를 얼러터블 상태로 변경
  • 28. 얼러터블 I/O  얼러터블 상태로 변경할 수 있는 함수 • SleepEx / WaitForSingleObjectEx / WaitForMultipleObjectsEx / SignalObjectAndWait / GetQueuedCompletionStatusEx / MsgWaitForMultipleObjectsEx  얼러터블 I/O의 장단점 • 장점 • 비동기 호출을 가능하게 만들어준다..ㅠ.ㅠ • 단일 스레드라서 동기화 처리를 할 필요가 없다. ㅠ.ㅠ • 단점 • 콜백함수 • 쓰레딩 문제
  • 29. I/O 컴플리션 포트 • 컨커런트 모델 • 컨커런트 모델을 사용하는 서비스 애플리케이션을 윈도우에서 구현 하였을 때 성능이 기대만큼 나오지 않자 개선해서 나온 결과로 태어난 것이 바로 I/O 컴플리션 포트 커널 오브젝트이다 • I/O 컴플리션 포트 생성 HANDLE CreateIoCompletionPort( HANDLE hFile, HANDLE hExistingCompletionPort, ULONG_PTR CompletionKey, DWORD dwNumberOfConcurrentThreads);
  • 30. I/O 컴플리션 포트 HANDLE CreateNewCompletionPort (DWORD dwThreads) { return CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, dwThreads); | • dwThreads • 동일 시간에 동시에 수행할 수 있는 스레드의 최대 개수 • 보통은 CPU 개수만큼을 입력
  • 31. I/O 컴플리션 포트 • I/O 컴플리션 포트 연계 HANDLE CreateIoCompletionPort( HANDLE hFile, HANDLE hExistingCompletionPort, ULONG_PTR CompletionKey, DWORD dwNumberOfConcurrentThreads); • hFile : 장치에 대한 핸들 (파일, 소켓, 메일슬롯, 파이프등) • hExistingCompletionPort : 생성해 둔 I/O 컴플리션 포트 핸들 • CompletionKey : 컴플리션 키 (사용자가 임의로 결정할 수 있다.)
  • 32. I/O 컴플리션 포트 • I/O 컴플리션 포트 연계 BOOL AssociateDeviceWithCompletionPort( HANDLE hDevice, HANDLE hExistingCompletionPort, ULONG_PTR CompletionKey,) { HANDLE h = CreateIoCompletionPort(hDevice, hCompletionPort, dwCompletionKey, 0); return (h == hCompletionPort); }
  • 33. I/O 컴플리션 포트 • 장치 리스트 • I/O 컴플리션 큐 • 대기 스레드 큐 • 릴리즈 스레드 리스트 • 일시 정지 스레드 리스트
  • 34. I/O 컴플리션 포트 커널 모드 Device List I/O Request List I/O Completion Queue 유저 모드 WSARecv() WSASend() GetQueuedCompletionS CreateCompletionPort ReadFileEX() tatus() …
  • 35. I/O 컴플리션 포트를 이용한 아키텍쳐 설계 • 클라이언트의 요청을 처리하는 스레드 풀 • 풀 내에 몇 개의 스레드를 생성해 두는 것이 좋은가? (다음발표자분) • 완료 통지가 전달 되었을 때 처리할 수 있도록 스레드를 대기 상태로!! BOOL GetQueuedCompletionStatus( HANDLE hCompletionPort, PDWORD pdwNumberOfBytesTransferred, PULONG_PTR pCompletionKey, OVERLAPPED** ppOverlapped, DWORD dwMilliseconds);
  • 36. I/O 컴플리션 포트를 이용한 아키텍쳐 설계 • 대기 스레드 큐 • 후입선출(LIFO) 방식으로 스레드를 깨운다. • 릴리즈 스레드 리스트 • I/O 컴플리션 포트가 대기 스레드 큐에 있는 스레드를 깨우는 경우 • 일시 정지되었던 스레드가 다시 깨어났을 경우 • 일시 정지 스레드 리스트 • 수행 중이던 스레드가 스레드를 정지시키는 함수를 호출 • 정지 중이던 스레드가 깨어나면 릴리즈 스레드 리스트로 삽입
  • 37. I/O 컴플리션 포트의 스레드 풀 관리방법 • I/O 컴플리션 포트 생성할 때 지정한 스레드 개수 이상을 초과할 수 없다 • 근데 왜?! 이보다 많은 스레드를 풀로 관리해야 하는가? • 릴리즈 스레드 리스트 • 대기 스레드 리스트  I/O 컴플리션 사용 목적  CPU가 계속해서 작업을 수행하도록 상태를 유지하는 것