180 likes | 470 Views
동기 및 비동기 장치 I/O. WVC++ Study 10 장. 최재 원. 목차. 장치 열기와 닫기 파일 장치 이용 동기 장치 I/O 수행 비동기 장치 I/O 수행 I/O 요청에 대한 완료 통지의 수신 IOCP. 1. 장치 열기와 닫기. 윈도우는 다양한 장치에 대한 읽기 , 쓰기 작업을 동일한 함수를 이용하여 수행할 수 있도록 함 다양한 장치들과 일반적인 사용 예 (p. 388~389) 다양한 장치를 열기 위한 함수들 (p. 389~390)
E N D
동기 및 비동기 장치 I/O WVC++ Study 10장 최재원
목차 • 장치 열기와 닫기 • 파일 장치 이용 • 동기 장치 I/O 수행 • 비동기 장치 I/O 수행 • I/O요청에 대한 완료 통지의 수신 • IOCP
1. 장치열기와 닫기 • 윈도우는 다양한 장치에 대한 읽기, 쓰기작업을 동일한 함수를 이용하여 수행할 수 있도록 함 • 다양한 장치들과 일반적인 사용 예 (p. 388~389) • 다양한 장치를 열기 위한 함수들 (p. 389~390) • CreateFile, CreateMailslot, CreateNamedPipe, CreatePipe, socket, accept, AcceptEx, … • 장치 닫기 함수들 • CloseHandle, closesocket • 장치의핸들로부터 장치 타입을 알아내는 함수 • GetFileType
1. 장치열기와 닫기 • CreateFile함수 (p. 391~399) • pszName • 장치 인스턴스를 나타내는 값, 장치의 타입 구분 • dwDesiredAccess • dwSharedMode • psa • dwCreateDisposition • dwFlagsAndAttributes • FILE_FLAG_OVERLAPPED : 장치에 비동기적 접근을 알려줌 • hFileTemplate
2. 파일 장치 이용 • 파일 크기 얻기 • GetFileSizeEx함수 • 파일의 논리적인 크기 • GetCompressedFileSize함수 • 파일의물리적인 크기 • 파일 포인터 위치 지정 • 파일 커널 오브젝트 내부적으로 파일 포인터를 가지고 있음 • 주의 : 커널 오브젝트당 하나의 파일 포인터 • P. 401 예제 참고 • SetFilePointerEx함수 • 파일의 끝 설정 • SetEndOfFile함수
3. 동기 장치 I/O 수행 • 반드시 FILE_FLAG_OVERLAPPED 플래그 없이 장치를 열어야 함 • ReadFile, WriteFile함수 • 장치로 데이터 플러시하기 • FlushFileBuffers함수 • 장치와 연관되어 있는 캐시된 데이터를 강제로 쓰도록 함 • 동기 I/O의 취소 • CancelSynchronousIo함수 • 해당 스레드가 동기I/O를 대기중이라면 작업을 취소 함 • 주의 : 해당 스레드가I/O 작업을 진행하고 있는지 알아내기가 어려움 (p. 406 참고)
4. 비동기 장치 I/O의 기본 • 배경 • 장치 I/O는 상대적으로 가장 느림 • 비동기I/O를 통해 성능을 높이고자 함 • 비동기I/O 처리 방식 • 스레드가비동기I/O 요청 • 장치의 디바이스드라이버로 전달 • 디바이스 드라이버는 실제 I/O를 하면서 장치로부터의 응답을 대기 • 따라서, 스레드는I/O 요청을 대기할 필요가 없음!!
4. 비동기 장치 I/O의 기본 • 반드시 FILE_FLAG_OVERLAPPED 플래그를 통해 장치를 열어야 함 • OVERLAPPED 구조체 (p. 408~410) • 노트: OVERLAPPED 구조체에 추가적인 컨텍스트 정보 포함방법 • 비동기 장치 I/O 사용 시 주의점 • 완료순서 보장 X • 에러 확인방법 • ERROR_IO_PENDING 인 경우 I/O요청 성공 • 데이터 버퍼와 OVERLAPPED 구조체의 메모리 해제 시점 • 반드시 I/O 완료될 때까지 삭제되지 않아야 함 • 요청된 장치 I/O의 취소 • P. 413 • I/O 요청이 취소되면 ERROR_OPERATION_ABORTED 에러 코드 반환
5. I/O 요청에 대한 완료 통지의 수신 • 디바이스 커널 오브젝트의 시그널링 • 이벤트 커널 오브젝트의 시그널링 • 얼러터블I/O 사용 • I/O 컴플리션 포트 사용
5. I/O 요청에 대한 완료 통지의 수신 • 디바이스 커널 오브젝트의 시그널링 • I/O 요청에 대한 처리를 마치면 디바이스 커널 오브젝트는 시그널 상태로 변경됨 • 다수의 I/O 요청에 대한 처리 수행 불가 • 어느 I/O 에 대한 시그널인지 알 수 없음 • 이벤트 커널 오브젝트의 시그널링 • OVERLAPPED 구조체의 hEvent멤버 사용 • 비동기I/O가 완료되면 디바이스 드라이버는 hEvent를 확인하여 NULL이 아닌경우SetEvent(hEvent)를 호출 함 • 각 비동기I/O 마다 서로 다른 이벤트 커널 오브젝트 생성 • 성능을 위해 파일 오브젝트를 시그널 상태로 변경 하지 않도록 SetFileCompletionNotificationMode함수 사용 (p. 417)
5. I/O 요청에 대한 완료 통지의 수신 • 얼러터블I/O 사용 • 시스템은 각 스레드별로비동기 프로시저 콜(APC) 큐를 생성 • 비동기I/O 요청시 디바이스 드라이버에게 I/O 완료 통지를 스레드의APC 큐에 삽입 요청 • ReadFileEx, WriteFileEx함수 사용 • OVERLAPPED 구조체의 hEvent멤버를 사용하지 않기 때문에 다른 용도로 사용 가능 • 스레드가얼러터블 상태가 되면 APC 큐의 내용 확인하여 컴플리션 루틴 수행 • 얼러터블 상태 변경 함수 • SleepEx, WaitFor…Ex, (p. 421~422) • APC 처리후 반환한 경우 WAIT_IO_COMPLETION 반환
5. I/O 요청에 대한 완료 통지의 수신 • 얼러터블I/O 사용 • 얼러터블I/O의 단점 • 콜백함수 • 스레딩 문제 • QueueUserAPC함수 • 사용자가 임의로 APC 큐에 항목을 추가할 수 있음 • 스레드를 대기 상태에서 강제로 빠져나오게 할 때 유용하게 사용 가능 (p. 425 예제)
5. I/O 요청에 대한 완료 통지의 수신 • I/O 컴플리션 포트 사용 • 시리얼 모델 • 하나의 스레드가 사용자의 요청 처리 • 컨커런트 모델 • 사용자 요청마다 스레드 생성 • 수많은 스레드들을 동시에 수행해야 함 -> 컨텍스트스위칭!! • I/O 컴플리션 포트 • 동시에 수행할 수 있는 스레드 개수의 상한을 설정 • 스레드 풀을 이용하여, 스레드 생성/소멸에 대한 오버헤드 제거
5. I/O 요청에 대한 완료 통지의 수신 • I/O 컴플리션 포트 사용 • CreateIoCompletionPort함수 • I/O 컴플리션 포트 생성 • 장치와 I/O 컴플리션 포트 연계 • 커널 오브젝트 중 유일하게 SECURITY_ATTRIBUTES 구조체를 인자로 받지 않음 • I/O 컴플리션 포트가 단일 프로세스 내에서만 수행되도록 하기 위함 • I/O 컴플리션 포트의 내부 자료구조 (p. 429) • 장치리스트 • I/O 컴플리션 큐 • 대기 스레드 큐 • 릴리즈스레드 리스트 • 일시 정지 스레드 리스트
5. I/O 요청에 대한 완료 통지의 수신 • I/O 컴플리션 포트 사용 • GetQueuedCompletionStatus(Ex) 함수 • 호출한 스레드의ID 값이 대기 스레드 큐에 삽입 됨 • I/O 컴플리션 큐에 항목이 추가되면 대기 스레드 큐에 있는 스레드 중 하나를 깨움 • I/O 컴플리션 큐는 FIFO 방식으로 처리됨 • 대기 스레드는LIFO 방식으로 깨어남 • Cache로 인한성능 향상을 위해
5. I/O 요청에 대한 완료 통지의 수신 • I/O 컴플리션 포트 사용 • 스레드 풀 관리 방법 (p. 435) • I/O 컴플리션 포트 생성시 동시에 수행 가능한 스레드 개수 지정 • 일반적으로 스레드 풀에는 좀 더 많은 스레드를 생성하여 관리 • I/O 컴플리션 포트는 항상 동시 수행 가능한 스레드 개수만큼 스레드가 깨어있도록 유지하려 함 • 실행중인 스레드(1)-> 대기 상태 전환 • I/O 컴플리션 포트 -> 대기 상태 스레드(2)를 깨움 • 대기중인 스레드(1) -> 수행 재개 • 동시 수행 가능한 스레드의 개수를 일시적으로 초과!! • 따라서, 스레드 풀 내의 스레드 개수는 동시에 수행 가능한 스레드 개수보다 큰 값으로 유지하는것이 좋음
5. I/O 요청에 대한 완료 통지의 수신 • I/O 컴플리션 포트 사용 • PostQueuedCompletionStatus함수 • I/O 컴플리션 큐에 항목 삽입 • 스레드간 통신을 수행할 때 유용하게 사용 가능