信号灯(用户模式 内核模式)
一.用户模式的信号灯
信号灯内部有个计数器,可以理解信号灯内部有N个灯泡,如果有一个灯泡亮着,就代表信号灯处于激发状态,如果全部熄灭,就代表信号灯处于未激发状态。
创建信号灯:
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,// pointer to security attributes
LONG lInitialCount, // initial count
LONG lMaximumCount, // maximum count
LPCTSTR lpName // pointer to semaphore-object name
);
增加信号灯的计数器:
BOOL ReleaseSemaphore(
HANDLE hSemaphore, // handle to the semaphore object
LONG lReleaseCount, // amount to add to current count
LPLONG lpPreviousCount // address of previous count
);
对信号灯执行一次等待操作,就会减少一个计数,就相当于熄灭一个灯泡。当计数为0时,也就是所有灯泡都熄灭时,当前线程进入睡眠状态,直到信号灯变成激发状态或者超时。
// Semaphore-ThreadSynchronization.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
void Sub_1();
HANDLE __SemaphoreHandle = NULL;
int main()
{
/*
HANDLE SemaphoreHandle = NULL;
HANDLE ThreadHandle = NULL;
SemaphoreHandle = CreateSemaphore(NULL, 2, 2, NULL); //创建两个亮着的灯泡
WaitForSingleObject(SemaphoreHandle, INFINITE); //熄灭一盏灯
ReleaseSemaphore(
SemaphoreHandle, //信号量的句柄
1, //增加个数
NULL); //用来传出先前的资源计数,设为NULL表示不需要传出
WaitForSingleObject(SemaphoreHandle, INFINITE);
WaitForSingleObject(SemaphoreHandle, INFINITE);
*/
__SemaphoreHandle = CreateSemaphore(
NULL, //安全结构
2, //初始资源数量
2, //最大并发数量
NULL); //匿名信号量
Sub_1();
printf("Input AnyKey To Exit\r\n");
getchar();
return 0;
}
void Sub_1()
{
WaitForSingleObject(__SemaphoreHandle, INFINITE);
printf("Sub_1()\r\n");
Sub_1();
}
二.内核模式下的信号灯
在内核模式下,信号灯对象用KSEMAPHORE数据结构表示。在使用信号灯对象钱,需要对其进行初始化(KeInitializeSemaphore)
KeReadStateSemaphore函数可以读取信号灯当前计数。
释放信号灯会增加信号灯计数,对应内核函数KeReleaseSemaphore函数。
#include "KSemaphore.h"
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
{
NTSTATUS Status = STATUS_SUCCESS;
PDEVICE_OBJECT DeviceObject = NULL;
DriverObject->DriverUnload = DriverUnload;
SeCreateSemaphore();
return Status;
}
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
DbgPrint("DriverUnload()\r\n");
}
VOID SeCreateSemaphore()
{
HANDLE ThreadHandle = NULL;
KSEMAPHORE Semaphore;
ULONG Count = 0;
PVOID ThreadObject = NULL;
KeInitializeSemaphore(&Semaphore, 2, 2);
Count = KeReadStateSemaphore(&Semaphore);
DbgPrint("Semaphore Count:%d\r\n", Count);
KeWaitForSingleObject(&Semaphore, Executive, KernelMode, FALSE, NULL);
Count = KeReadStateSemaphore(&Semaphore);
DbgPrint("Semaphore Count:%d\r\n", Count);
KeWaitForSingleObject(&Semaphore, Executive, KernelMode, FALSE, NULL);
PsCreateSystemThread(&ThreadHandle, 0, NULL, NULL, NULL, ThreadProcedure, &Semaphore);
KeWaitForSingleObject(&Semaphore, Executive, KernelMode, FALSE, NULL);
ObReferenceObjectByHandle(ThreadHandle, 0, NULL, KernelMode, &ThreadObject, NULL);
KeWaitForSingleObject(ThreadObject, Executive, KernelMode, FALSE, NULL);
ZwClose(ThreadHandle);
}
VOID ThreadProcedure(PVOID ParameterData)
{
PKSEMAPHORE Semaphore = (PKSEMAPHORE)ParameterData;
KeReleaseSemaphore(Semaphore, IO_NO_INCREMENT, 1, FALSE);
PsTerminateSystemThread(STATUS_SUCCESS);
}
浙公网安备 33010602011771号