Windows驱动开发WDM (8)- 内核同步对象

只要写过多线程应用的程序员都知道,多线程访问公共资源的时候需要同步。在用户模式下,经常使用事件,互斥,信号量等对象来控制公共资源的访问。内核模式下,也是有相应的事件,互斥,信号量等内核对象,还有自旋锁。如果不是用同步对象进行控制,那么当多线程访问的时候就会产生一些不可预测的问题了。 不使用同步对象看下面的代码:NTSTATUS Encoding(IN PDEVICE_OBJECT
摘要由CSDN通过智能技术生成

只要写过多线程应用的程序员都知道,多线程访问公共资源的时候需要同步。在用户模式下,经常使用事件,互斥,信号量等对象来控制公共资源的访问。内核模式下,也是有相应的事件,互斥,信号量等内核对象,还有自旋锁。如果不是用同步对象进行控制,那么当多线程访问的时候就会产生一些不可预测的问题了。

 

不使用同步对象

看下面的代码:

NTSTATUS Encoding(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
	KdPrint(("Start to Encode\n"));
	
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	//得到输入缓冲区大小
	ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;

	//得到输出缓冲区大小
	ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;

	//获取输入缓冲区,IRP_MJ_DEVICE_CONTROL的输入都是通过buffered io的方式
	char* inBuf = (char*)Irp->AssociatedIrp.SystemBuffer;

	//假如需要将数据放到一个公共资源中,然后再进行操作,比如这里是亦或编码,那么就需要考虑同步的问题。
	//不然在多线程调用的时候,公共资源的访问将会有不可预测的问题。
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;

	RtlCopyMemory(pdx->buffer, inBuf, cbin);

	//模拟延时3秒
	KdPrint(("Wait 3s\n"));
	KEVENT event;
	KeInitializeEvent(&event, NotificationEvent, FALSE);
	LARGE_INTEGER timeout;
	timeout.QuadPart = -3 * 1000 * 1000 * 10;//负数表示从现在开始计数,KeWaitForSingleObject的timeout是100ns为单位的。
	KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, &timeout);//等待3秒

	for (ULONG i = 0; i < cbin; i++)//将输入缓冲区里面的每个字节和m亦或
	{
		pdx->buffer[i] = pdx->buffer[i] ^ 'm';
	}

	//获取输出缓冲区,这里使用了直接方式,见CTL_CODE的定义,使用了METHOD_IN_DIRECT。所以需要通过直接方式获取out buffer
	KdPrint(("user address: %x, this address should be same to user mode addess.\n", MmGetMdlVirtualAddress(Irp->MdlAddress)))
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值