内核事件KEVENT(同步)

转载请您注明出处:http://www.cnblogs.com/lsh123/p/7358702.html

一.驱动程序与驱动程序的事件交互    IoCreateNotificationEvent ———> IoCreateNotificationEvent

  

  在内核驱动中可以通过给某个内核对象创建一个命名对象,然后在另一个驱动中通过名字来获取这个对象,然后操作它来实现两个驱动之间的内核对象的通讯,针对事件对象来说,要实现两个驱动交互事件对象,通过这样几步:

1. 在驱动Server中调用IoCreateNotificationEvent或者IoCreateSynchronizationEvent来创建一个通知事件对象或者同步事件对象

2. 在驱动Client中调用
IoCreateNotificationEvent或者IoCreateSynchronizationEvent获取已经有名字的内核对象的句柄 ,设置事件的激发状态
(3. 在驱动B中调用ObReferenceObjectByHandle根据上面两个函数返回的句柄来获取A中的事件对象,并操作它)

源代码:

Server.c

#include <ntifs.h>
#define EVENT_NAME  L"\\BaseNamedObjects\\ServerKernelEvent"

void ThreadProcedure(PVOID ParameterData);
VOID DriverUnload(PDRIVER_OBJECT DriverObject);

PKEVENT __Event;
HANDLE __EventHandle;

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
{
	NTSTATUS Status = STATUS_SUCCESS;
	UNICODE_STRING  EventName;
	PDEVICE_OBJECT  DeviceObject = NULL;
	HANDLE   ThreadHandle = NULL;
	CLIENT_ID       ClientID = { 0 };

	DriverObject->DriverUnload = DriverUnload;

	RtlInitUnicodeString(&EventName, EVENT_NAME);
	DriverObject->DriverUnload = DriverUnload;

	__Event = IoCreateNotificationEvent(
		&EventName,                    //自定义事件名
		&__EventHandle);               //返回的事件句柄
	KeResetEvent(__Event);

	Status = PsCreateSystemThread(&ThreadHandle, 0, NULL, NtCurrentProcess(), &ClientID,
		(PKSTART_ROUTINE)ThreadProcedure,NULL);

	return Status;
}

void ThreadProcedure(PVOID ParameterData)
{
	NTSTATUS Status;
	KeWaitForSingleObject(__Event, Executive, KernelMode, FALSE, NULL);
	DbgPrint("ThreadProcedure() Exit\r\n");
	PsTerminateSystemThread(STATUS_SUCCESS);
}

VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
	DbgPrint("DriverUnload()\r\n");
	if (__EventHandle != NULL)
	{
		KeClearEvent(__Event);

		ZwClose(__EventHandle);

		__EventHandle = NULL;
		__Event = NULL;
	}

}

Client.c

#include <ntifs.h>

#define EVENT_NAME  L"\\BaseNamedObjects\\ServerKernelEvent"
VOID DriverUnload(PDRIVER_OBJECT DriverObject);

PKEVENT __Event;
HANDLE __EventHandle;
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
{
	NTSTATUS Status = STATUS_SUCCESS;
	UNICODE_STRING  EventName;
	PDEVICE_OBJECT  DeviceObject = NULL;
	DriverObject->DriverUnload = DriverUnload;
	RtlInitUnicodeString(&EventName, EVENT_NAME);
	__Event = IoCreateNotificationEvent(&EventName, &__EventHandle);    //获取已经有名字的内核对象的句柄
	KeSetEvent(__Event, IO_NO_INCREMENT, FALSE);                        //设置激发态
	return Status;
}

VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
	DbgPrint("DriverUnload()\r\n");
	if (__EventHandle != NULL)
	{
		KeClearEvent(__Event);
		ZwClose(__EventHandle);
		__EventHandle = NULL;
		__Event = NULL;
	}

}

  

二.驱动程序与应用程序的事件交互(驱动程序创建事件——>应用程序设置事件)IoCreateNotificationEvent ——> OpenEvent

  应用程序中创建的事件和在内核模式下创建的事件对象,本质上是同一个东西。在用户模式下,它用句柄代表,在内核模式下,它用KEVENT数据结构代表。
在应用程序中,所有内核对象都不会被用户看到,用户看到的只是代表内核对象的对象句柄。

  __Event = IoCreateNotificationEvent(&EventName, &__EventHandle); //DriverEntry 进程回调通知

  EventHandle = OpenEvent(
    SYNCHRONIZE, //请求访问权限
    FALSE, // 不继承
    L"Global\\Ring0KernelEvent"); //事件对象名称

  1.驱动程序IoCreateNotificationEvent创建事件
  2.应用程序OpenEvent得到事件句柄

Ring3.cpp

// Ring3(设置).cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;

int main()
{

	HANDLE EventHandle = NULL;

	while (TRUE)
	{
		EventHandle = OpenEvent(
			SYNCHRONIZE,          //请求访问权限
			FALSE,                // 不继承
			L"Global\\Ring0KernelEvent"); //事件对象名称

		if (EventHandle == NULL)
		{
			continue;
		}

		break;
	}

	cout << "Ring3等待" << endl;
	while (TRUE)
	{

		int Index = WaitForSingleObject(EventHandle, 3000);

		Index = Index - WAIT_OBJECT_0;

		if (Index == WAIT_TIMEOUT)
		{

			//注意这里当驱动卸载并关闭事件时事件对象是不能够得到及时的销毁 因为应用层占用了该对象
			//所以我们长时间等待不到授信 就关闭并重新打开
			if (EventHandle != NULL)
			{
				CloseHandle(EventHandle);
				EventHandle = NULL;
				EventHandle = OpenEvent(SYNCHRONIZE, FALSE, L"Global\\Ring0KernelEvent");

				if (EventHandle == NULL)
				{
					cout << "对象已经不存在" << endl;
					break;
				}
			}

			continue;
		}

		if (Index == 0)            //有信号状态
		{
			cout << "Ring0触发Ring3" << endl;
		}

		if (Index == WAIT_FAILED)
		{
			break;
		}

		Sleep(1);
	}

	cout << "Input AnyKey To Exit" << endl;

	getchar();
	if (EventHandle != NULL)
	{
		CloseHandle(EventHandle);
		EventHandle = NULL;

	}
	return 0;
}

  

Ring0.c

#include <ntifs.h>

#define EVENT_NAME  L"\\BaseNamedObjects\\Ring0KernelEvent"
VOID DriverUnload(PDRIVER_OBJECT DriverObject);

PKEVENT __Event;
HANDLE __EventHandle;

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
{
	NTSTATUS Status = STATUS_SUCCESS;
	PDEVICE_OBJECT  DeviceObject = NULL;
	UNICODE_STRING  EventName;

	RtlInitUnicodeString(&EventName, EVENT_NAME);
	DriverObject->DriverUnload = DriverUnload;

	__Event = IoCreateNotificationEvent(&EventName, &__EventHandle);    //DriverEntry     进程回调通知

	return Status;
}

VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
	DbgPrint("DriverUnload()\r\n");

	if (__EventHandle != NULL)
	{
		KeClearEvent(__Event);

		ZwClose(__EventHandle);

		__EventHandle = NULL;
		__Event = NULL;
	}

}

  

三.应用程序与驱动程序的事件交互(应用程序创建事件——>驱动程序设置事件) DeviceIoControl ——> ObReferenceObjectByHandle

  要将用户模式下创建的事件传递给驱动程序,可以用DeviceIoControl API函数。DDK提供了内核函数将句柄转化为指针,该函数如下:
  NTSTATUS 
     ObReferenceObjectByHandle(
      IN HANDLE  Handle,
      IN ACCESS_MASK  DesiredAccess,
      IN POBJECT_TYPE  ObjectType  OPTIONAL,
      IN KPROCESSOR_MODE  AccessMode,
      OUT PVOID  *Object,
      OUT POBJECT_HANDLE_INFORMATION  HandleInformation  OPTIONAL
      );

  ObReferenceObjectByHandle函数在得到指针的同时,会为对象的指针维护一个计数。每次调用ObReferenceObjectByHandle函数时会使计数加1.因此为了计数平衡,在使用完 ObReferenceObjectByHandle函数后,需要调用如下函数:             
  VOID 
    ObDereferenceObject(
      IN PVOID  Object
      );
  ObDereferenceObject函数使计数减一。

  1.应用程序通过符号链接名由CreateFile函数得到设备句柄

  HANDLE DeviceHandle = CreateFile(DeviceLinkName,
    GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);
  2.应用程序CreateEvent创建事件

    //创建自动重置的,初始为未激发的事件对象
    EventHandle[i] = CreateEvent(NULL, FALSE, FALSE, NULL);

  3.应用程序通过DeviceIoControl 函数将用户模式下创建的事件传递给驱动程序

    //调用DeviceIoControl把事件句柄传进内核
    IsOk = DeviceIoControl(DeviceHandle, CTL_EVENT,
      EventHandle,
      sizeof(HANDLE) * 2,
      NULL,
      0,
      &ReturnLength,
      NULL);

    //调用DeviceIoControl,通知驱动程序设置事件激发状态
    IsOk = DeviceIoControl(DeviceHandle, CTL_SET_EVENT,
      NULL,
      0,
      NULL,
      0,
      &ReturnLength,
      NULL);

  4.驱动程序通过ObReferenceObjectByHandle将句柄转化为PKEVENT指针

    /把句柄转化为KEvent结构
    Status = ObReferenceObjectByHandle(
      (HANDLE)EventHandle[i], //Irp->AssociatedIrp.SystemBuffer 句柄
      SYNCHRONIZE, //权限
      *ExEventObjectType, //对象类型,对象类型
      KernelMode, //访问模式分KernelMode
      &__KernelEvent[i], //指向映射句柄对象的指针
      NULL);

Ring3.cpp

#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;

#define CTL_EVENT 	CTL_CODE(FILE_DEVICE_UNKNOWN,0x830,METHOD_BUFFERED,FILE_ANY_ACCESS)

#define CTL_SET_EVENT 	CTL_CODE(FILE_DEVICE_UNKNOWN,0x831,METHOD_BUFFERED,FILE_ANY_ACCESS)

HANDLE SeOpenDeviceObject(WCHAR* DeviceLinkName);
DWORD WINAPI ThreadProcedure(LPVOID ParameterData);
int main()
{
	HANDLE DeviceHandle = SeOpenDeviceObject(L"\\\\.\\Ring0DeviceLinkName");
	if (DeviceHandle == NULL)
	{
		return 0;
	}

	ULONG i = 0;
	HANDLE EventHandle[3] = { 0 };
	for (i = 0; i < 3; i++)
	{
		//创建自动重置的,初始为未激发的事件对象
		EventHandle[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
	}
	BOOL IsOk = 0;
	DWORD ReturnLength = 0;
	//调用DeviceIoControl把事件句柄传进内核
	IsOk = DeviceIoControl(DeviceHandle, CTL_EVENT,
		EventHandle,
		sizeof(HANDLE) * 2,
		NULL,
		0,
		&ReturnLength,
		NULL);

	if (IsOk == FALSE)
	{
		goto Exit;
	}

	HANDLE  ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProcedure,
		(PVOID)EventHandle, 0, NULL);
	//调用DeviceIoControl,通知驱动程序设置事件激发状态
	IsOk = DeviceIoControl(DeviceHandle, CTL_SET_EVENT,
		NULL,
		0,
		NULL,
		0,
		&ReturnLength,
		NULL);

	if (IsOk == FALSE)
	{
		cout << "Send IoCode Error" << endl;
		SetEvent(EventHandle[2]);
		WaitForSingleObject(ThreadHandle, INFINITE);
		goto Exit;
	}

	WaitForSingleObject(ThreadHandle, INFINITE);

Exit:
	{
		for (i = 0; i < 3; i++)
		{
			if (EventHandle[i] != NULL)
			{
				CloseHandle(EventHandle[i]);
				EventHandle[i] = NULL;
			}
		}
		if (ThreadHandle != NULL)
		{
			CloseHandle(ThreadHandle);
			ThreadHandle = NULL;
		}
		if (DeviceHandle != NULL)
		{
			CloseHandle(DeviceHandle);
			DeviceHandle = NULL;
		}
	}

	printf("卸载驱动后 Input AnyKey To Exit\r\n");
	getchar();
	getchar();

	return 0;

}

DWORD WINAPI ThreadProcedure(LPVOID ParameterData)
{

	cout << "Ring3等待" << endl;
	//等待三个之中有激发状态的信号
	DWORD Index = WaitForMultipleObjects(3, (HANDLE*)ParameterData, FALSE, INFINITE);
	Index = Index - WAIT_OBJECT_0;
	if (Index == 2)  //0 1 2
	{
		printf("ThreadProcedure() Exit\r\n");
		return 0;
	}
	cout << "Ring0触发Ring3" << endl;
	cout << "输入任意键Ring3触发Ring0" << endl;

	getchar();
	getchar();

	SetEvent(((HANDLE*)ParameterData)[1]);  //Ring0中KeWaitForSingleObject响应
	printf("ThreadProcedure() Exit\r\n");
	return 0;
}

HANDLE SeOpenDeviceObject(WCHAR* DeviceLinkName)
{
	HANDLE DeviceHandle = CreateFile(DeviceLinkName,
		GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL);

	if (DeviceHandle == INVALID_HANDLE_VALUE)
	{
		return NULL;
	}

	return DeviceHandle;

}

  

Ring0.c

#include <ntifs.h>

#define CTL_EVENT 	CTL_CODE(FILE_DEVICE_UNKNOWN,0x830,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define CTL_SET_EVENT 	CTL_CODE(FILE_DEVICE_UNKNOWN,0x831,METHOD_BUFFERED,FILE_ANY_ACCESS)

#define DEVICE_OBJECT_NAME  L"\\Device\\Ring0DeviceObjectName"
//设备与设备之间通信
#define DEVICE_LINK_NAME    L"\\DosDevices\\Ring0DeviceLinkName"
NTSTATUS PassThroughDispatch(PDEVICE_OBJECT  DeviceObject, PIRP Irp);
NTSTATUS ControlThroughDispatch(PDEVICE_OBJECT  DeviceObject, PIRP Irp);
VOID DriverUnload(PDRIVER_OBJECT DriverObject);
NTSTATUS Ring3EventHandleToRing0KernelEvent(HANDLE* EventHandle, ULONG_PTR EventHandleCount);

PKEVENT  __KernelEvent[20] = { 0 };
ULONG_PTR __KernelEventCount = 0;

extern
POBJECT_TYPE* ExEventObjectType;

NTSTATUS DriverEntry(PDRIVER_OBJECT  DriverObject, PUNICODE_STRING  RegisterPath)
{
	UNREFERENCED_PARAMETER(RegisterPath);
	NTSTATUS Status = STATUS_SUCCESS;
	PDEVICE_OBJECT  DeviceObject = NULL;
	UNICODE_STRING  DeviceObjectName;
	UNICODE_STRING  DeviceLinkName;
	ULONG			i;
	DriverObject->DriverUnload = DriverUnload;

	//创建设备对象名称
	RtlInitUnicodeString(&DeviceObjectName, DEVICE_OBJECT_NAME);

	//创建设备对象
	Status = IoCreateDevice(DriverObject, NULL,
		&DeviceObjectName,
		FILE_DEVICE_UNKNOWN,
		0, FALSE,
		&DeviceObject);
	if (!NT_SUCCESS(Status))
	{
		return Status;
	}
	//创建设备连接名称
	RtlInitUnicodeString(&DeviceLinkName, DEVICE_LINK_NAME);

	//将设备连接名称与设备名称关联
	Status = IoCreateSymbolicLink(&DeviceLinkName, &DeviceObjectName);

	if (!NT_SUCCESS(Status))
	{
		IoDeleteDevice(DeviceObject);
		return Status;
	}
	//设计符合我们代码的派遣历程
	for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
	{
		DriverObject->MajorFunction[i] = PassThroughDispatch;   //函数指针
	}
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ControlThroughDispatch;

	return STATUS_SUCCESS;
}

NTSTATUS ControlThroughDispatch(PDEVICE_OBJECT  DeviceObject, PIRP Irp)
{

	NTSTATUS Status = STATUS_UNSUCCESSFUL;
	ULONG_PTR Information = 0;
	PVOID InputData = NULL;
	ULONG InputDataLength = 0;
	PVOID OutputData = NULL;
	ULONG OutputDataLength = 0;
	ULONG IoControlCode = 0;
	PEPROCESS EProcess = NULL;
	PIO_STACK_LOCATION  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);  //Irp堆栈
	IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode;
	InputData = Irp->AssociatedIrp.SystemBuffer;
	OutputData = Irp->AssociatedIrp.SystemBuffer;
	InputDataLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength;
	OutputDataLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength;
	switch (IoControlCode)
	{
	case CTL_EVENT:
	{

		if (InputData != NULL&&InputDataLength == sizeof(HANDLE)*2)
		{

			Status = Ring3EventHandleToRing0KernelEvent((HANDLE*)InputData, InputDataLength / sizeof(HANDLE));

		}

		Information = 0;

		break;

	}

	case CTL_SET_EVENT:
	{

		DbgPrint("Ring0触发Ring3\r\n");
		KeSetEvent(__KernelEvent[0], IO_NO_INCREMENT, FALSE);  //Ring3层线程中WaitForMultipleObjects响应

		DbgPrint("Ring0等待\r\n");
		Status = KeWaitForSingleObject(__KernelEvent[1],
			Executive, KernelMode, FALSE, NULL);    //注意这里的最后一个参数NULL 是永久等待

		DbgPrint("Ring3触发Ring0\r\n");

		Information = 0;
		break;

	}

	default:
	{

		Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
		Irp->IoStatus.Information = 0;

		break;
	}
	}

	Irp->IoStatus.Status = Status;
	Irp->IoStatus.Information = Information;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return Status;
}

NTSTATUS Ring3EventHandleToRing0KernelEvent(HANDLE* EventHandle, ULONG_PTR EventHandleCount)
{
	NTSTATUS   Status = STATUS_SUCCESS;
	PULONG_PTR HandleArray = NULL;
	ULONG i = 0;

	if (EventHandle==NULL)
	{
		return STATUS_UNSUCCESSFUL;
	}
	__KernelEventCount = EventHandleCount;
	for (i = 0; i < EventHandleCount; i++)
	{
		//把句柄转化为KEvent结构
		Status = ObReferenceObjectByHandle(
			(HANDLE)EventHandle[i],           //Irp->AssociatedIrp.SystemBuffer   句柄
			SYNCHRONIZE,                      //权限
			*ExEventObjectType,               //对象类型,对象类型
			KernelMode,                       //访问模式分KernelMode
			&__KernelEvent[i],                //指向映射句柄对象的指针
			NULL);
		if (!NT_SUCCESS(Status))
		{
			break;
		}
	}

	if (Status != STATUS_SUCCESS)
	{
		for (i = 0; i < EventHandleCount; i++)
		{
			if (__KernelEvent[i] != NULL)
			{
				//递减计数
				ObDereferenceObject(__KernelEvent[i]);

				__KernelEvent[i] = NULL;
			}
		}
	}
	return Status;
}

NTSTATUS PassThroughDispatch(PDEVICE_OBJECT  DeviceObject, PIRP Irp)
{
	Irp->IoStatus.Status = STATUS_SUCCESS;     //LastError()
	Irp->IoStatus.Information = 0;             //ReturnLength
	IoCompleteRequest(Irp, IO_NO_INCREMENT);   //将Irp返回给Io管理器
	return STATUS_SUCCESS;
}

VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
	int i = 0;
	UNICODE_STRING  DeviceLinkName;
	PDEVICE_OBJECT	v1 = NULL;
	PDEVICE_OBJECT  DeleteDeviceObject = NULL;

	RtlInitUnicodeString(&DeviceLinkName, DEVICE_LINK_NAME);
	IoDeleteSymbolicLink(&DeviceLinkName);

	DeleteDeviceObject = DriverObject->DeviceObject;
	while (DeleteDeviceObject != NULL)
	{
		v1 = DeleteDeviceObject->NextDevice;
		IoDeleteDevice(DeleteDeviceObject);
		DeleteDeviceObject = v1;
	}
	for (i = 0; i < __KernelEventCount; i++)
	{
		if (__KernelEvent[i] != NULL)
		{
			ObDereferenceObject(__KernelEvent[i]);

			__KernelEvent[i] = NULL;
		}
	}
}

  

时间: 2024-10-11 16:01:56

内核事件KEVENT(同步)的相关文章

线程与内核对象的同步

线程与内核对象的同步内核对象可以处于已通知或未通知状体进程,线程,作业,文件,控制台输入,文件修改,事件,可等待定时器 等待函数DWORD WaitForSingleObject(HANDLE hobject, DWORD dwMilliseconds); 同时查看若干个内核对象已通知状体DWORD WaitForMultipleObjects(DWORD dwCount,CONST HANDLE* phObjects,BOOL fWaitAll,DWORD dwMilliseconds);dw

Windows API学习---线程与内核对象的同步

前言 若干种内核对象,包括进程,线程和作业.可以将所有这些内核对象用于同步目的.对于线程同步来说,这些内核对象中的每种对象都可以说是处于已通知或未通知的状态之中.这种状态的切换是由Microsoft为每个对象建立的一套规则来决定的.例如,进程内核对象总是在未通知状态中创建的.当进程终止运行时,操作系统自动使该进程的内核对象处于已通知状态.一旦进程内核对象得到通知,它将永远保持这种状态,它的状态永远不会改为未通知状态. 当进程正在运行的时候,进程内核对象处于未通知状态,当进程终止运行的时候,它就变

深入理解Linux内核day04--内核同步

内核同步 你可以把内核看作是不断对请求响应的服务器,这些请求可能来自在CPU上执行的进程,也可能来自发出中断请求的外部设备. 内核如何为不同的请求提供服务 为了更好的理解内核代码是如何执行的,我们把内核看作必须满足两种请求的侍者:一种请求来自于顾客,另一种请求来自数量有限的几个不同的老板. 对不同的请求,侍者采用如下的策略: 1.老板提出请求时,如果侍者正空闲,则侍者开始为老板服务. 2.如果老板提出请求时侍者正在为顾客服务,那么侍者停止为顾客服务,转而去为老板服务. 3.如果一个老板提出请求时

【同步】孙鑫VC++笔记-事件对象同步

事件对象同步 //CreateEvent设置自定的,并且初始有信号#include<windows.h> #include<iostream.h> DWORD WINAPI ThreadProc1( LPVOID lpParameter ); DWORD WINAPI ThreadProc2( LPVOID lpParameter ); int tickes=100; HANDLE g_hEvent; int main() { HANDLE hThread1=CreateThrea

线程与内核对象的同步-2

等待定时器内核事件CreateWaitableTimer(PSECURITY_ATTRIBUTES psa,BOOL fManualReset,PCTSTR pszName);进程可以获得它自己的与进程相关的现有等待定时器的句柄.HANDLE OpenWaitableTimer(DWORD dwDesiredAccess,BOOL bInheritHandle,PCTSTR pszName); 等待定时器对象总是在未通知状态中创建,必须调用SetWaitableTimer函数来告诉定时器你想在何

[转载] 《重要》内核下各种同步处理方法(自旋锁、信号灯、互斥体…)

本文转载自: http://www.blogfshare.com/kernel-synchronization.html 1.在支持多线程的操作系统下,有些函数会出现不可重入的现象.所谓“可重入”是指函数的执行结果不和执行顺序有关.反之如果执行结果和执行顺序有关,则称这个函数是“不可重入”的. 2.Windows将中断的概念进行了扩展,提出一个中断请求级(IRQL)的概念.其中规定了32个中断请求级别,分别是0~2级别为软件中断,3~31级为硬件中断,其中数字从0~31,优先级别逐次递增. 在内

协程,事件,队列,同步,异步,回调函数

协程 什么是协成?单个线程并发的处理多个任务,程序控制协成的切换+保持状态,协成的切换速度非常快,蒙蔽了操作系统的眼睛,让操作系统认为CPU一直在运行 进程或线程都是由操作系统控制CPU来回切换,遇到阻塞就切换执行其他任务,协成是程序控制的,霸占CPU执行任务,会在操作系统控制CPU之前来回切换,操作系统就认为CPU一直在运作 协程的优点: 1.开销小 2.运行速度快 3.协程会长期霸占CPU只执行我程序里的所有任务 协程的缺点: 1.协程属于微并发,处理任务不易过多 2.协程的本质是单线程,无

python-Event事件线程同步和互斥

1 #!/usr/bin/python 2 #coding=utf-8 3 #用于线程间通信,通过事件标识控制 4 import threading 5 from time import sleep,ctime 6 7 def A(): 8 print "A is starting" 9 event_is_set=e.wait() 10 print "event set1:%s"%event_is_set 11 12 def B(e,t): 13 while not

Linux内核同步机制

http://blog.csdn.net/bullbat/article/details/7376424 Linux内核同步控制方法有很多,信号量.锁.原子量.RCU等等,不同的实现方法应用于不同的环境来提高操作系统效率.首先,看看我们最熟悉的两种机制——信号量.锁. 一.信号量 首先还是看看内核中是怎么实现的,内核中用struct semaphore数据结构表示信号量(<linux/semphone.h>中): [cpp] view plaincopyprint? struct semaph