비동기 프로시저 호출
APC(비동기 프로시저 호출)는 특정 스레드의 컨텍스트에서 비동기적으로 실행되는 함수입니다. APC가 스레드에 큐에 대기하는 경우 시스템은 소프트웨어 인터럽트를 실행합니다. 다음에 스레드가 예약되면 APC 함수를 실행합니다. 시스템에서 생성된 APC를 커널 모드 APC. 애플리케이션에서 생성된 APC를 사용자 모드 APC. 사용자 모드 APC를 실행하려면 스레드가 경고 가능한 상태여야 합니다.
각 스레드에는 자체 APC 큐가 있습니다. 애플리케이션은 QueueUserAPC 함수를 호출하여 APC를 스레드에 큐에 대기합니다. 호출 스레드는 queueUserAPC 호출에서 APC 함수의 주소를 지정합니다. APC의 큐는 스레드가 APC 함수를 호출하도록 요청하는 요청입니다.
사용자 모드 APC가 큐에 대기 중인 경우 경고 가능 상태가 아닌 한 대기 중인 스레드는 APC 함수를 호출하도록 지시되지 않습니다. 스레드는 SleepEx, SignalObjectAndWait, MsgWaitForMultipleObjectsEx, WaitForMultipleObjectsEx또는 WaitForSingleObjectEx 함수를 호출할 때 경고 상태가 됩니다. APC가 큐에 대기되기 전에 대기가 충족되면 스레드가 더 이상 경고 대기 상태가 아니므로 APC 함수가 실행되지 않습니다. 그러나 APC는 여전히 큐에 대기되므로 스레드가 경고 가능한 다른 대기 함수를 호출할 때 APC 함수가 실행됩니다.
ReadFileEx, setWaitableTimer, SetWaitableTimerEx및 WriteFileEx 함수는 완료 알림 콜백 메커니즘으로 APC를 사용하여 구현됩니다.
스레드 풀사용하는 경우 시스템이 스레드 풀 스레드의 수명을 제어하므로 알림이 전달되기 전에 스레드를 종료할 수 있으므로 API는 다른 신호 메커니즘뿐만 아니라 작동하지 않습니다. SetWaitableTimer 또는 SetWaitableTimerExpfnCompletionRoutine 매개 변수와 같은 APC 기반 신호 메커니즘을 사용하는 대신 CreateThreadpoolTimer사용하여 만든 타이머와 같은 대기 가능한 개체를 사용합니다. I/O의 경우 CreateThreadpoolIo 사용하여 만든 I/O 완성 개체 또는 이벤트가 SetThreadpoolWait 함수에 전달될 수 있는 hEvent기반 OVERLAPPED 구조를 사용합니다.
동기화 내부
I/O 요청이 실행되면 요청을 나타내기 위해 구조체가 할당됩니다. 이 구조를 IRP(I/O 요청 패킷)라고 합니다. 동기 I/O를 사용하면 스레드가 IRP를 빌드하고, 디바이스 스택으로 보내고, 커널에서 IRP가 완료되기를 기다립니다. 비동기 I/O를 사용하여 스레드는 IRP를 빌드하고 디바이스 스택으로 보냅니다. 스택이 IRP를 즉시 완료하거나 요청이 진행 중임을 나타내는 보류 중인 상태를 반환할 수 있습니다. 이 경우 IRP는 여전히 스레드와 연결되므로 스레드가 종료되거나 CancelIo같은 함수를 호출하는 경우 취소됩니다. 한편 디바이스 스택이 IRP를 계속 처리하는 동안 스레드는 다른 작업을 계속 수행할 수 있습니다.
시스템에서 IRP가 완료되었음을 나타낼 수 있는 몇 가지 방법이 있습니다.
- 스레드가 폴링하여 작업이 완료되었는지 여부를 확인할 수 있도록 겹치는 구조를 작업 결과로 업데이트합니다.
- 스레드가 이벤트에서 동기화되고 작업이 완료될 때 해제될 수 있도록 겹치는 구조에서 이벤트를 신호로 표시합니다.
- 스레드가 경고 대기 상태가 될 때 APC 루틴을 실행하고 하나 이상의 APC 루틴을 실행했음을 나타내는 상태로 대기 작업에서 반환되도록 스레드의 보류 중인 APC에 IRP를 대기합니다.
- IRP를 I/O 완료 포트로 큐에 대기합니다. 이 포트는 완료 포트에서 대기하는 다음 스레드에 의해 실행됩니다.
I/O 완료 포트에서 대기하는 스레드는 경고 가능한 상태에서 기다리지 않습니다. 따라서 이러한 스레드가 스레드에 대한 APC로 완료되도록 설정된 IRP를 발급하는 경우 해당 IPC 완성은 적시에 발생하지 않습니다. 스레드가 I/O 완료 포트에서 요청을 선택한 다음 경고 대기를 입력하는 경우에만 발생합니다.
관련 항목
-
비동기 프로시저 호출 대기 가능 타이머 사용