모든 드라이버는 세마포 개체를 사용하여 드라이버에서 만든 스레드와 다른 드라이버 루틴 간에 작업을 동기화할 수 있습니다. 예를 들어 드라이버 전용 스레드는 드라이버에 대한 미해결 I/O 요청이 없는 경우 대기 상태로 전환될 수 있으며, 드라이버의 디스패치 루틴은 IRP를 큐에 대기한 직후에 세마포를 Signaled 상태로 설정할 수 있습니다.
I/O 작업을 요청하는 스레드의 컨텍스트에서 실행되는 최상위 드라이버의 디스패치 루틴은 세마포를 사용하여 디스패치 루틴 간에 공유되는 리소스를 보호할 수 있습니다. 동기 I/O 작업에 대한 하위 수준 드라이버 디스패치 루틴은 세마포를 사용하여 해당 디스패치 루틴의 하위 집합 또는 드라이버에서 만든 스레드와 공유되는 리소스를 보호할 수도 있습니다.
세마포 개체를 사용하는 모든 드라이버는 세마포를 기다리거나 해제하기 전에 KeInitializeSemaphore 호출해야 합니다. 다음 그림에서는 스레드가 있는 드라이버가 세마포 개체를 사용하는 방법을 보여 줍니다.
세마포 개체 대기를 보여 주는 
이전 그림과 같이 이러한 드라이버는 상주해야 하는 세마포 개체에 대한 스토리지를 제공해야 합니다. 드라이버는 드라이버에서 만든 디바이스 개체의 디바이스 확장, 컨트롤러 개체사용하는 경우 컨트롤러 확장 또는 드라이버가 할당한 비페이지 풀을 사용할 수 있습니다.
드라이버의 AddDevice 루틴이 KeInitializeSemaphore 호출하는 경우 세마포 개체에 대한 드라이버의 상주 스토리지에 대한 포인터를 전달해야 합니다. 또한 호출자는 이전 그림과 같이 초기 상태(Signaled의 경우 0이 아닌 경우)를 결정하는 세마포 개체에 대한 Count 지정해야 합니다.
호출자는 다음 중 하나일 수 있는 세마포에 대한 제한 지정해야 합니다.
제한 = 1
이 세마포가 Signaled 상태로 설정되면 세마포가 Signaled 상태로 설정되기를 기다리는 단일 스레드가 실행될 수 있으며 세마포로 보호되는 리소스에 액세스할 수 있습니다.
이러한 유형의 세마포는 스레드가 세마포로 보호되는 리소스에 대한 단독 액세스 권한이 있거나 없는 이진 세마포 호출됩니다.
제한 > 1
이 세마포가 Signaled 상태로 설정되면 세마포 개체가 Signaled 상태로 설정되기를 기다리는 일부 스레드가 실행될 수 있으며 세마포로 보호되는 리소스에 액세스할 수 있습니다.
세마포를 신호 상태로 설정하는 루틴은 대기 상태에서 준비 상태로 상태를 변경할 수 있는 대기 스레드 수를 지정하기 때문에 이러한 유형의 세마포를 카운트 세마포라고 합니다. 이러한 대기 스레드의 수는 세마포가 초기화되었을 때 제한 설정되거나 이 미리 설정된 제한보다 적은 수일 수 있습니다.
단일 드라이버가 만든 스레드가 있는 디바이스 또는 중간 드라이버는 거의 없습니다. 세마포를 획득하거나 해제할 때까지 기다릴 수 있는 스레드 집합이 더 적습니다. 시스템 제공 드라이버가 세마포 개체를 사용하는 경우는 거의 없으며 이진 세마포를 사용하는 드라이버도 적습니다. 이진 세마포는 뮤텍스 개체기능에서 유사해 보일 수 있지만, 이진 세마포는 SMP 머신에서 실행되는 시스템 스레드에 대해 뮤텍스 개체가 갖는 교착 상태에 대한 기본 제공 보호를 제공하지 않습니다.
초기화된 세마포가 있는 드라이버가 로드되면 공유 리소스를 보호하는 세마포에 대한 작업을 동기화할 수 있습니다. 예를 들어 시스템 플로피 컨트롤러 드라이버와 같이 IRP의 큐를 관리하는 디바이스 전용 스레드가 있는 드라이버는 이전 그림과 같이 세마포에서 IRP 큐를 동기화할 수 있습니다.
스레드는 초기화된 세마포 개체를 대기 상태로 전환하기 위해 드라이버 제공 스토리지에 대한 포인터를 사용하여 KeWaitForSingleObject 호출합니다.
디바이스 I/O 작업이 필요한 IRP가 들어오기 시작합니다. 드라이버의 디스패치 루틴은 스핀 잠금 제어 아래의 연결된 큐에 각 IRP를 삽입하고 세마포 개체에 대한 포인터를 사용하여 KeReleaseSemaphore 호출합니다. 이전 그림과 같이 스레드(증가)에 대한 드라이버 결정 우선 순위 상승으로, 각 IRP가 큐에 대기될 때 세마포 수에 추가되는 조정 1입니다. 부울 Wait FALSE 설정됩니다. 0이 아닌 세마포 개수는 세마포 개체를 Signaled 상태로 설정하여 대기 중인 스레드의 상태를 준비 상태로 변경합니다.
커널은 프로세서를 사용할 수 있는 즉시 실행을 위해 스레드를 디스패치합니다. 즉, 우선 순위가 높은 다른 스레드가 현재 준비 상태에 있지 않으며 더 높은 IRQL에서 실행할 커널 모드 루틴이 없습니다.
스레드는 스핀 잠금 제어 아래의 연동된 큐에서 IRP를 제거하고, 추가 처리를 위해 다른 드라이버 루틴에 전달하고, keWaitForSingleObject 호출하면 다시. 세마포가 여전히 신호됨 상태로 설정되어 있는 경우(즉, 해당 개수가 0이 아닌 상태로 유지되어 더 많은 IRP가 드라이버의 연동 큐에 있음을 나타낸다) 커널은 스레드의 상태가 준비될 때까지 기다리지 않도록 다시 변경합니다.
이러한 방식으로 카운팅 세마포를 사용하면 이러한 드라이버 스레드는 스레드가 실행될 때마다 연동된 큐에서 제거할 IRP를 "알고 있습니다".
KeReleaseSemaphore호출할 때 IRQL을 관리하는 방법에 대한 자세한 내용은 KeReleaseSemaphore설명 섹션을 참조하세요.
PASSIVE_LEVEL보다 큰 IRQL에서 실행되는 표준 드라이버 루틴은 시스템을 중단하지 않고 디스패처 개체에서 0이 아닌 간격을 기다릴 수 없습니다. 자세한 내용은 커널 디스패처 개체 참조하세요. 그러나 이러한 루틴은 DISPATCH_LEVEL 작거나 같은 IRQL에서 실행되는 동안 KeReleaseSemaphore 호출할 수 있습니다.
표준 드라이버 루틴이 실행되는 IRQL에 대한 요약은 하드웨어 우선 순위 관리 참조하세요. 특정 지원 루틴의 IRQL 요구 사항은 루틴의 참조 페이지를 참조하세요.