제10장. 동기 및 비동기 장치 IO

Download Report

Transcript 제10장. 동기 및 비동기 장치 IO

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