信号灯(用户模式 内核模式)
一.用户模式的信号灯
信号灯内部有个计数器,可以理解信号灯内部有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时,也就是所有灯泡都熄灭时,当前线程进入睡眠状态,直到信号灯变成激发状态或者超时。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | // 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函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #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); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗