대기 함수

대기 함수를 사용하면 스레드가 자체 실행을 차단할 수 있습니다. 대기 함수는 지정된 조건이 충족될 때까지 반환되지 않습니다. 대기 함수의 유형은 사용되는 조건 집합을 결정합니다. 대기 함수가 호출되면 대기 조건이 충족되었는지 여부를 확인합니다. 조건이 충족되지 않으면 대기 조건의 조건이 충족되거나 지정된 시간 제한 간격이 경과할 때까지 호출 스레드가 대기 상태가 됩니다.

단일 개체 대기 함수

SignalObjectAndWait, WaitForSingleObjectWaitForSingleObjectEx 함수에는 하나의 동기화 개체에 대한 핸들이 필요합니다. 이러한 함수는 다음 중 하나가 발생할 때 를 반환합니다.

  • 지정된 개체가 신호 상태입니다.
  • 제한 시간 간격이 경과합니다. 시간 제한 간격을 INFINITE 로 설정하여 대기 시간이 초과되지 않도록 지정할 수 있습니다.

SignalObjectAndWait 함수를 사용하면 호출 스레드가 개체의 상태를 신호로 원자성으로 설정하고 다른 개체의 상태가 신호로 설정될 때까지 기다릴 수 있습니다.

다중 개체 대기 함수

WaitForMultipleObjects, WaitForMultipleObjectsEx, MsgWaitForMultipleObjectsMsgWaitForMultipleObjectsEx 함수를 사용하면 호출 스레드가 하나 이상의 동기화 개체 핸들을 포함하는 배열을 지정할 수 있습니다. 이러한 함수는 다음 중 하나가 발생할 때 를 반환합니다.

  • 지정된 개체 중 하나의 상태가 신호로 설정되었거나 모든 개체의 상태가 신호로 설정되었습니다. 함수 호출에서 하나 또는 모든 상태를 사용할지 여부를 제어합니다.
  • 제한 시간 간격이 경과합니다. 시간 제한 간격을 INFINITE 로 설정하여 대기 시간이 초과되지 않도록 지정할 수 있습니다.

MsgWaitForMultipleObjectsMsgWaitForMultipleObjectsEx 함수를 사용하면 개체 핸들 배열에 입력 이벤트 개체를 지정할 수 있습니다. 이 작업은 스레드의 입력 큐에서 대기할 입력 유형을 지정할 때 수행됩니다. 예를 들어 스레드는 MsgWaitForMultipleObjects 를 사용하여 지정된 개체의 상태가 신호로 설정되고 스레드의 입력 큐에서 사용할 수 있는 마우스 입력이 있을 때까지 실행을 차단할 수 있습니다. 스레드는 GetMessage 또는 PeekMessageA 또는 PeekMessageW 함수를 사용하여 입력을 검색할 수 있습니다.

모든 개체의 상태가 신호로 설정되기를 기다리는 경우 이러한 다중 개체 함수는 모든 개체의 상태가 신호를 받을 때까지 지정된 개체의 상태를 수정하지 않습니다. 예를 들어 뮤텍스 개체의 상태는 신호를 받을 수 있지만 배열에 지정된 다른 개체의 상태도 신호로 설정될 때까지 호출 스레드는 소유권을 얻지 못합니다. 그 동안 일부 다른 스레드는 뮤텍스 개체의 소유권을 얻을 수 있으므로 상태를 비사인으로 설정할 수 있습니다.

단일 개체의 상태가 신호로 설정되기를 기다리는 경우 이러한 다중 개체 함수는 개체 중 하나가 신호를 받을 때까지 인덱스 0부터 시작하여 배열의 핸들을 검사. 여러 개체가 신호를 받으면 함수는 개체가 신호를 받은 배열에서 첫 번째 핸들의 인덱스 를 반환합니다.

경고 대기 함수

MsgWaitForMultipleObjectsEx, SignalObjectAndWait, WaitForMultipleObjectsExWaitForSingleObjectEx 함수는 필요에 따라 경고 대기 작업을 수행할 수 있다는 점에서 다른 대기 함수와 다릅니다. 경고 대기 작업에서 함수는 지정된 조건이 충족될 때 를 반환할 수 있지만 시스템이 대기 스레드에서 실행하기 위해 I/O 완료 루틴 또는 APC를 큐에 대기하는 경우에도 반환할 수 있습니다. 경고 대기 작업 및 I/O 완료 루틴에 대한 자세한 내용은 동기화 및 겹치는 입력 및 출력을 참조하세요. APC에 대한 자세한 내용은 비동기 프로시저 호출을 참조하세요.

등록된 대기 함수

RegisterWaitForSingleObject 함수는 대기 작업이 스레드 풀의 스레드에 의해 수행된다는 점에서 다른 대기 함수와 다릅니다. 지정된 조건이 충족되면 스레드 풀의 작업자 스레드에 의해 콜백 함수가 실행됩니다.

기본적으로 등록된 대기 작업은 다중 대기 작업입니다. UnregisterWaitEx 함수를 호출하여 작업을 취소할 때까지 시스템은 이벤트가 신호를 수신할 때마다(또는 시간 제한 간격이 경과할 때마다) 타이머를 다시 설정합니다. 대기 작업을 한 번만 실행하도록 지정하려면 RegisterWaitForSingleObjectdwFlags 매개 변수를 WT_EXECUTEONLYONCE 설정합니다.

스레드가 APC를 사용하는 함수를 호출하는 경우 RegisterWaitForSingleObjectdwFlags 매개 변수를 WT_EXECUTEINPERSISTENTTHREAD 설정합니다.

주소 대기 중

스레드는 WaitOnAddress 함수를 사용하여 대상 주소의 값이 원치 않는 값에서 다른 값으로 변경될 때까지 기다릴 수 있습니다. 이렇게 하면 스레드가 원치 않는 값을 캡처하지만 스레드가 대기하기 전에 값이 변경될 때 발생할 수 있는 동기화 문제를 회전하거나 처리하지 않고도 값이 변경될 때까지 기다릴 수 있습니다.

대상 값을 수정하는 코드가 WakeByAddressSingle을 호출하여 단일 대기 스레드를 절전 모드 해제하거나 WakeByAddressAll을 호출하여 모든 대기 스레드를 절전 모드 해제하여 변경 신호를 보내면 WaitOnAddress가 반환됩니다. WaitOnAddress를 사용하여 제한 시간 간격을 지정하고 스레드가 절전 모드 해제 함수를 호출하지 않으면 시간 제한 간격이 경과하면 함수가 반환됩니다. 제한 시간 간격을 지정하지 않으면 스레드가 무기한 대기합니다.

대기 함수 및 시간 제한 간격

지정된 시간 제한 간격의 정확도는 시스템 클록의 해상도에 따라 달라집니다. 시스템 클록은 일정한 속도로 "틱"합니다. 시간 제한 간격이 시스템 클록의 해상도보다 작으면 대기 시간이 지정된 시간보다 작을 수 있습니다. 제한 시간 간격이 1틱보다 크지만 2보다 작으면 대기는 1~2틱 사이일 수 있습니다.

대기 함수에 대한 제한 시간 간격의 정확도를 높이려면 timeGetDevCaps 함수를 호출하여 지원되는 최소 타이머 해상도를 확인하고 timeBeginPeriod 함수를 호출하여 타이머 해상도를 최소값으로 설정합니다. timeBeginPeriod를 호출할 때는 잦은 호출이 시스템 클록, 시스템 전원 사용량 및 스케줄러에 큰 영향을 줄 수 있으므로 주의해야 합니다. timeBeginPeriod를 호출하는 경우 애플리케이션에서 일찍 한 번 호출하고 애플리케이션의 맨 끝에 timeEndPeriod 함수를 호출해야 합니다.

대기 함수 및 동기화 개체

대기 함수는 일부 유형의 동기화 개체의 상태를 수정할 수 있습니다. 수정은 신호 상태가 함수가 반환되도록 한 개체 또는 개체에 대해서만 발생합니다. 대기 함수는 다음과 같이 동기화 개체의 상태를 수정할 수 있습니다.

  • 세마포 개체의 개수가 1씩 감소하고, 세마포의 개수가 0이면 세마포의 상태가 부호 없는 상태로 설정됩니다.
  • 뮤텍스, 자동 재설정 이벤트 및 변경 알림 개체의 상태는 서명되지 않은 상태로 설정됩니다.
  • 동기화 타이머의 상태는 서명되지 않은 상태로 설정됩니다.
  • 수동 재설정 이벤트, 수동 재설정 타이머, 프로세스, 스레드 및 콘솔 입력 개체의 상태는 대기 함수의 영향을 받지 않습니다.

대기 함수 및 Windows 만들기

직접 또는 간접적으로 창을 만드는 대기 함수 및 코드를 사용할 때는 주의해야 합니다. 스레드가 창을 만드는 경우 메시지를 처리해야 합니다. 메시지 브로드캐스트는 시스템의 모든 창으로 전송됩니다. 시간 제한 간격 없이 대기 함수를 사용하는 스레드가 있는 경우 시스템이 교착 상태가 됩니다. 간접적으로 창을 만드는 코드의 두 가지 예는 DDE 및 CoInitialize 함수입니다. 따라서 창을 만드는 스레드가 있는 경우 다른 대기 함수 대신 MsgWaitForMultipleObjects 또는 MsgWaitForMultipleObjectsEx를 사용합니다.