4-19 비동기 I/O와 APC
- I/O와 클럭
- 비동기 I/O
- 중첩 I/O
- 완료 루틴 기반 I/O
- 알람 가능한 상태(Alertable State) & APC(Asynchronous Procedure Call)
I/O와 클럭
ex) 1초에 100번의 연산(100클럭)을 하는 A시스템과 1초에 200번의 연산(200클럭)을 하는 B시스템이 있는 경우
-> 100클럭의 연산데이터를 버퍼를 통해 전송하고 버퍼는 10 클럭마다 비워진다고(전송된다고) 가정
-> A 시스템은 연산에 1초가 소요되며 데이터를 10개로 분할하여 전송
-> B 시스템은 연산에 0.5초가 소요되며 데이터를 20개로 분할하여 전송
-> 일반적으로는 B 시스템(클럭이 높은)이 더 빨라 보이나, 이는 핸드 쉐이크 등 과정이 2배로 사용되는 것을 의미
클럭이 빠른 시스템 != 데이터를 전송하는 속도가 빠른 시스템
-> 오히려 클럭이 높아도 더 늘릴 수 있음
-> I/O 연산에서 클럭이 차지하는 영향력은 미비
-> 사용자가 직접 설계 가능한 '버퍼를 비우는 정책'이 데이터 전송에 직접적인 영향
비동기 I/O
ex) Write 함수가 호출되는 순간 데이터가 전송되고, 함수가 반환되는 순간 데이터 전송이 마무리된다고 가정
동기 I/O 모델
동기 모델의 경우 함수의 호출과 데이터의 전송이 동기화
-> 함수의 반환과 데이터 전송의 끝이 동기화되어 있는 모델
-> Write 함수를 호출하고 데이터 전송이 완료되기 이전까지 함수가 반환되지 않음
-> 함수 반환 전까지 다른 작업 불가 = CPU가 Blocking 상태에 있음
-> 상기 사진 상 CPU 사용률이 0%에 수렴했을 때가 함수 호출 후 반환 이전(Block 상태)인 경우
비동기 I/O 모델
비동기 모델은 Write 함수 호출 순간에 데이터가 전송되지만 반환 시점이 데이터 전송의 끝을 의미하지 않음
-> Write 함수 호출과 동시에 반환이 이루어지고 내부적으로 데이터 전송을 수행
-> Write 함수가 반환되었기에 I/O 연산 도중에도 다른 작업 수행 가능
-> 상기 사진을 확인하면 동기 모델에 비해 CPU 사용률이 어느 정도 일정한 모습(병렬적으로 작업 처리)
중첩 I/O 모델
I/O 함수를 호출하고 반환하기 이전에 다른 I/O 함수를 호출하여 호출을 중첩하는 방식
-> CPU는 I/O를 수행할 때 느리고, 대기하는 시간도 있기 때문에 중첩하여 대기하는 시간을 줄일 수 있음
완료 루틴 기반 I/O 모델
I/O 연산이 완료되고 추후 작업을 진행하기 위해서는 I/O 연산이 종료되었는지 확인해야 함
-> 모든 I/O의 완료 여부를 확인하는 것은 시스템 입장에서 부담
-> 완료 루틴 기반 모델은 I/O 연산이 마무리되면 그 이후 루틴을 자동으로 실행할 수 있는 구조
-> 별도의 연산 완료 확인 과정 없이 이후 작업을 수행할 수 있는 장점
중첩 I/O
중첩 I/O 구조
1. 리소스 생성 시 FILE_FLAG_OVERLAPPED를 인자로 전달하고 리소스 전달(파일, 파이프 등)
2. OverLapeed 구조체를 통해 비동기 I/O를 진행
3. 연산이 마무리되면 이벤트가 Signaled 상태로 전환
Overlapped 구조체
WriteFile() & GetOverlappedResult()
WriteFile() : 데이터 전송 수행
GetOverlappedResult() : 전송한 데이터 확인
-> 중첩 I/O는 비동기 I/O이기 때문에 WriteFile() 함수가 반환된 이후라도 전송 직후에 데이터 확인은 불가능
-> 데이터 전송이 실제로 마무리 된 이후 시점부터 해당 함수를 통한 데이터 확인 가능
완료 루틴 기반 I/O
완료 루틴 기반 I/O 구조
완료 루틴 기반 I/O = 중첩 I/O를 확장한 개념
-> 중첩 I/O에 사용된 Overlapped 구조체를 초기화해서 사용
-> 중첩 I/O에 완료 루틴 함수를 추가하고 I/O 연산이 마무리 되면 호출되는 함수가 추가되어 연관 관계 구성
-> 완료 루틴 함수가 호출되면 I/O 연산의 종료를 알 수 있기 때문에 Overlapped 구조체의 Event 핸들 필요하지 않음
완료 루틴 기반 I/O 함수
WriteFileEx() : 데이터 전송 수행
-> Comlpetion_Routine 인자는 호출 대상이 사용자가 아닌 Window OS
-> 함수를 선언하면 인자를 Windows OS가 전달
FileIOCompletionRoutine() : 연산 완료 루틴 수행
알람 가능한 상태(Alertable State) & APC(Asynchronous Procedure Call)
알람 가능한 상태
I/O 연산이 완료되면 완료 루틴을 실행해야하는데, 이 루틴의 실행 타이밍과 관련
-> SleepEx() 함수를 호출하여 두번째 인자로 true 를 전달하면 해당 스레드는 알람 가능한 상태로 전환
-> 완료 루틴 실행
APC
비동기 함수 호출 메커니즘
모든 스레드는 자신만의 APC 큐를 소유
-> APC 큐 : 스레드가 알람 가능한 상태가 되었을 때, 호출할 함수를 모아놓은 큐
-> QueueUserAPC() : APC 큐에 호출하고자 하는 함수의 정보를 전달하는 함수
-> SleepEx() 함수를 통해 특정 스레드를 알람 가능한 상태로 전환(완료 루틴 실행 준비)
-> QueueUserAPC()를 통해 앞선 스레드의 특정 함수(완료 루틴)를 호출
'Study > Windows System Programming' 카테고리의 다른 글
[Window System Programming] Chapter 21. DLL (0) | 2024.02.10 |
---|---|
[Window System Programming] Chapter 20. 가상 메모리 & 힙 컨트롤 / MMF (1) | 2024.02.10 |
[Window System Programming] Chapter 18. 파일 I/O와 디렉토리 컨트롤 (1) | 2024.01.21 |
[Window System Programming] Chapter 17. 예외 처리 / SEH & 종료 핸들러 / 예외 핸들러 (0) | 2024.01.20 |
[Window System Programming] Chapter 16. 메모리 계층 / 캐쉬와 캐쉬 알고리즘 / 가상 메모리 (0) | 2024.01.20 |