프로그래밍/소켓 프로그래밍 입문

APC(Asynchronous Procedure Call) 알아보기

데일리 백수 2025. 1. 25. 20:58

1. APC(Asynchronous Procedure Call)란?

APC는 윈도우 운영체제에서 특정 스레드에게 나중에 실행되도록 예약하는 콜백 함수를 의미합니다.

  • 비동기 I/O가 완료되었을 때, 혹은 QueueUserAPC 호출 등을 통해 “이 함수를 이 스레드에서 실행해 달라”는 요구를 큐에 넣고, 스레드가 Alertable Wait 상태로 들어갈 때 즉시 함수가 실행됩니다.

즉, APC는 “스레드 문맥(Context)에서 실행되는 콜백 함수”라고 정리할 수 있습니다.

 

2. APC 작동 구조

  1. APC Queue
    • 스레드마다 독립된 APC 큐가 존재.
    • 하나의 스레드가 여러 개의 APC를 등록할 수 있음.
  2. APC 등록
    • 예: QueueUserAPC(&MyApcFunction, hThread, dwParam);
    • I/O 완료 시에도, OS가 자동으로 “이 스레드의 APC 큐에 콜백 등록” (WriteFileEx, ReadFileEx 등).
  3. APC 실행
    • 해당 스레드가 Alertable Wait 상태(SleepEx, WaitForSingleObjectEx(…, TRUE))로 들어가면, OS는 APC Queue에 쌓인 함수를 꺼내 실행 → 즉시 콜백 함수 진입.
    • APC 실행이 끝나면 스레드가 다시 wait 상태로 돌아가거나, wait 함수가 WAIT_IO_COMPLETION을 반환.

3. Alertable Wait가 필요한 이유

APC는 “스레드 문맥”에서 동작하므로, 스레드가 다음과 같은 상황이 아닐 땐 APC 콜백 함수가 실행될 기회가 없습니다:

  1. 스레드가 일반 Wait(블록) 중일 경우
    • WaitForSingleObject(hEvent, INFINITE)처럼 Alertable 모드가 아니면, APC가 대기 중이어도 실행되지 못함.
  2. 스레드가 Busy-Running(실행 중) 상태일 경우
    • CPU 연산을 계속하는 중에는 APC가 바로 끼어들지 못함. (단, 커널이 Thread State 전환을 할 때 기회를 얻게 될 수 있으나 일반적으론 Alertable이 필요).
  3. 스레드가 Alertable Wait(SleepEx(…), TRUE or WaitForSingleObjectEx(…, TRUE)) 상태일 경우
    • OS가 “이 스레드에 등록된 APC가 있네? → 바로 콜백 실행” 방식을 취함.

이러한 구조로 인해, APC 기반 콜백을 받으려면 Alertable Wait가 필수입니다.


4. APC와 비동기 I/O 예시

  • WriteFileEx, ReadFileEx:
    • 비동기(Overlapped) 모드 I/O 함수를 호출할 때, Completion Routine(콜백) 주소를 전달.
    • I/O가 완료되면 OS가 그 스레드에 “이 콜백을 실행하라”는 APC를 추가.
    • 스레드가 SleepEx(…, TRUE) 등으로 들어가면, APC가 실행 → “I/O가 끝났네! dwBytesTransferred = …”.

정리: “APC = I/O 완료 시점에 실행되는 콜백” → “Alertable Wait = 스레드가 APC를 받아줄 준비가 된 상태”.


5. APC의 활용 범위

  1. 비동기 파일·소켓 I/O(Overlapped + Ex 함수)
    • I/O 완료 알림을 APC로 받아 처리.
  2. 사용자 정의 QueueUserAPC
    • 임의의 함수를 다른 스레드의 문맥에서 실행할 수 있음(간단한 스레드 간 메시지·함수 호출 용도).
  3. Timer APC
    • 타이머가 만료됐을 때, 특정 스레드의 APC를 실행.

6. APC 사용 시 주의할 점

  1. Alertable Wait가 없으면 콜백 실행 불가
    • 스레드가 일반 WaitForSingleObject로 블로킹 중이면 APC는 대기 중.
  2. APC는 Thread별
    • APC는 “특정 스레드의 문맥에서만” 실행. 다른 스레드에 주입할 수도 있지만, 그 스레드가 alertable 모드로 들어가야 콜백을 받음.
  3. 동기화
    • APC 콜백 내에서 전역 변수나 공유 자원을 사용할 때, 스레드 동기화가 필요. 예: 크리티컬 섹션, 뮤텍스 등.

7. 정리

APC(Asynchronous Procedure Call)는 Windows에서 비동기 이벤트(특히 I/O 완료)를 Alertable Wait 방식으로 스레드에게 알리는 콜백 메커니즘입니다:

  1. 등록: OS나 사용자 코드가 “이 스레드에서 이것(콜백 함수)을 실행해 달라”고 요청 → APC Queue에 적재.
  2. 실행: 스레드가 Alertable Wait에 들어가면, OS가 APC Queue의 함수(콜백)을 불러준다.
  3. 종료: 콜백 함수 실행 후 스레드는 원래 Wait 상태로 돌아가거나 WAIT_IO_COMPLETION을 반환.

비동기 I/O(WriteFileEx 등) 완료 시점을 전통적 이벤트(WAIT) 대신, APC 콜백으로 처리함으로써, 코드가 더욱 이벤트 드리븐 형태가 되고, I/O 완료 시점에 직접 함수를 실행해 바로 로직을 처리할 수 있다는 장점이 있습니다.