동기화 및 겹치는 입력 및 출력
파일, 명명된 파이프 및 직렬 통신 디바이스에서 동기 또는 비동기(겹침이라고도 함) I/O 작업을 수행할 수 있습니다. WriteFile, ReadFile, DeviceIoControl, waitCommEvent, ConnectNamedPipe및 TransactNamedPipe 함수는 동기 또는 비동기적으로 수행할 수 있습니다. ReadFileEx 및 WriteFileEx 함수는 비동기적으로만 수행할 수 있습니다.
함수가 동기적으로 실행되면 작업이 완료될 때까지 반환되지 않습니다. 즉, 시간이 많이 걸리는 작업이 완료될 때까지 기다리는 동안 호출 스레드의 실행을 무기한으로 차단할 수 있습니다. 작업이 완료되지 않았더라도 겹치는 작업에 대해 호출된 함수는 즉시 반환될 수 있습니다. 이렇게 하면 호출 스레드가 다른 작업을 자유롭게 수행할 수 있는 동안 백그라운드에서 시간이 많이 걸리는 I/O 작업을 실행할 수 있습니다. 예를 들어 단일 스레드는 다른 핸들에서 동시 I/O 작업을 수행하거나 동일한 핸들에서 동시 읽기 및 쓰기 작업을 수행할 수 있습니다.
겹치는 작업의 완료와 실행을 동기화하기 위해 호출 스레드는 GetOverlappedResult 함수, GetOverlappedResultEx 함수 또는 대기 함수 중 하나를 사용하여 겹치는 작업이 완료된 시기를 확인합니다. HasOverlappedIoCompleted 매크로를 사용하여 완료를 폴링할 수도 있습니다.
보류 중인 모든 비동기 I/O 작업을 취소하려면 CancelIoEx 함수를 사용하고 취소 요청을 지정하는 OVERLAPPED 구조를 제공합니다. CancelIo 함수를 사용하여 지정된 파일 핸들에 대해 호출 스레드에서 발급한 보류 중인 비동기 I/O 작업을 취소합니다.
겹치는 작업에는 FILE_FLAG_OVERLAPPED 플래그를 사용하여 만든 파일, 명명된 파이프 또는 통신 디바이스가 필요합니다. 스레드가 겹치는 작업을 수행하기 위해 함수(예: ReadFile 함수)를 호출하는 경우 호출 스레드는 OVERLAPPED 구조체에 대한 포인터를 지정해야 합니다. (이 포인터가 NULL 함수 반환 값이 작업이 완료되었음을 잘못 나타낼 수 있습니다.) 이벤트가 I/O 작업의 완료를 알리는 데 사용되지 않는 한 OVERLAPPED 구조체의 모든 멤버를 0으로 초기화해야 합니다. 이벤트를 사용하는 경우 OVERLAPPED 구조체의 hEvent 멤버는 할당된 이벤트 개체에 대한 핸들을 지정합니다. 시스템은 작업이 완료되기 전에 I/O 함수에 대한 호출이 반환될 때 이벤트 개체의 상태를 서명되지 않은 상태로 설정합니다. 시스템은 작업이 완료될 때 이벤트 개체의 상태를 신호로 설정합니다. 이벤트는 동시에 둘 이상의 미해결 I/O 작업이 있는 경우에만 필요합니다. 이벤트가 사용되지 않는 경우 완료된 각 I/O 작업은 파일, 명명된 파이프 또는 통신 디바이스에 신호를 전송합니다.
겹치는 작업을 수행하기 위해 함수가 호출되면 함수가 반환되기 전에 작업이 완료될 수 있습니다. 이 경우 작업이 동기적으로 수행된 것처럼 결과가 처리됩니다. 그러나 작업이 완료되지 않은 경우 함수의 반환 값은 FALSE GetLastError 함수는 ERROR_IO_PENDING반환합니다.
스레드는 다음 두 가지 방법 중 하나를 통해 겹치는 작업을 관리할 수 있습니다.
- GetOverlappedResult 또는 GetOverlappedResultEx 함수를 사용하여 겹치는 작업이 완료될 때까지 기다립니다. getOverlappedResultEx 사용하는 경우 호출 스레드는 겹치는 작업에 대한 시간 제한을 지정하거나 경고 대기를 수행할 수 있습니다.
- 대기 함수 중 하나에서 OVERLAPPED 구조체의 수동 재설정 이벤트 개체에 대한 핸들을 지정한 다음 대기 함수가 반환된 후 GetOverlappedResult 호출하거나 GetOverlappedResultEx. 이 함수는 겹쳐진 완료된 작업의 결과를 반환하며, 이러한 정보가 적절한 함수의 경우 전송된 실제 바이트 수를 보고합니다.
단일 스레드에서 여러 개의 동시 겹치는 작업을 수행하는 경우 호출 스레드는 각 작업에 대해 OVERLAPPED 구조를 지정해야 합니다. 각 OVERLAPPED 구조체는 다른 수동 재설정 이벤트 개체에 대한 핸들을 지정해야 합니다. 겹치는 작업 중 하나가 완료될 때까지 기다리려면 스레드는 다중 개체 대기 함수 중 하나에서 모든 수동 재설정 이벤트 핸들을 대기 조건으로지정합니다. 다중 개체 대기 함수의 반환 값은 신호를 받은 수동 재설정 이벤트 개체를 나타내므로 스레드는 대기 작업이 완료된 겹치는 작업을 확인할 수 있습니다.
이벤트 개체를 지정하거나 여러 작업에 동일한 이벤트 개체를 다시 사용하는 대신 겹치는 각 작업에 별도의 이벤트 개체를 사용하는 것이 더 안전합니다. OVERLAPPED 구조에 이벤트 개체가 지정되지 않은 경우 겹치는 작업이 완료되면 시스템에서 파일, 명명된 파이프 또는 통신 디바이스의 상태를 알릴 수 있습니다. 따라서 이러한 핸들을 대기 함수에서 동기화 개체로 지정할 수 있지만, 이 용도로 사용하기는 어려울 수 있습니다. 동일한 파일, 명명된 파이프 또는 통신 디바이스에서 동시에 겹치는 작업을 수행할 때 어떤 작업으로 인해 개체의 상태가 신호를 수신했는지 알 수 없기 때문입니다.
스레드는 해당 스레드의 겹치는 작업으로만 이벤트가 신호를 받을 것이라는 가정 하에 이벤트를 다시 사용해서는 안 됩니다. 완료 중인 겹치는 작업과 동일한 스레드에서 이벤트가 신호로 전송됩니다. 여러 스레드에서 동일한 이벤트를 사용하면 해당 이벤트를 사용하는 다른 스레드에 대해 작업이 먼저 완료되고 조기에 완료되는 스레드에 대해 이벤트가 올바르게 신호되는 경합 상태가 발생할 수 있습니다. 그런 다음 겹치는 다음 작업이 완료되면 겹치는 모든 작업이 완료될 때까지 해당 이벤트를 사용하는 모든 스레드에 대해 이벤트가 다시 신호로 전송됩니다.
겹치는 작업, 완료 루틴 및 GetOverlappedResult 함수의 사용을 보여 주는 예제는 파이프 사용하는참조하세요.
Windows Vista, Windows Server 2003 및 Windows XP:
OVERLAPPED 구조를 다시 사용할 때는 주의해야 합니다. OVERLAPPED 구조체가 여러 스레드에서 재사용되고 GetOverlappedResultbWait 매개 변수를 TRUE설정된 상태에서 호출하는 경우 호출 스레드는 구조를 다시 사용하기 전에 연결된 이벤트가 신호를 받도록 해야 합니다. 이 작업은 GetOverlappedResult 호출한 후 WaitForSingleObject 함수를 사용하여 스레드가 작업이 완료될 때까지 대기하도록 강제하여 수행할 수 있습니다. 이벤트 개체는 수동 재설정 이벤트 개체여야 합니다. 자동 설정 이벤트 개체를 사용하는 경우 bWait 매개 변수를 사용하여 GetOverlappedResult 호출하면 TRUE 함수가 무기한 차단됩니다. 이 동작은 Windows 7을 애플리케이션 매니페스트에서 지원되는 운영 체제로 지정하는 애플리케이션의 경우 Windows 7 및 Windows Server 2008 R2부터 변경되었습니다. 자세한 내용은 애플리케이션 매니페스트참조하세요.
관련 항목