使用线程时出现Windows WriteFile问题

时间:2011-09-01 15:26:47

标签: c++ windows multithreading driver createfile

我的公司正在开发需要与软件通信的硬件。为此,我们制作了一个驱动程序,可以写入和读取硬件。要访问驱动程序,我们使用命令:

HANDLE device = CreateFile(DEVICE_NAME,
                                GENERIC_READ | GENERIC_WRITE,
                                0x00000007,
                                &sec,
                                OPEN_EXISTING,
                                0,
                                NULL);

使用以下函数完成读写:

WriteFile(device,&package,package.datasize,&bytesWritten,NULL);

ReadFile(device,returndata,returndatasize,&bytesRead,NULL);

最后,CloseHandle(设备),关闭文件。

在从主线程调用函数的情况下,这很好用。如果从其他某个线程调用它们,则在尝试写入多个元素时会出现错误998(no_acccess)。线程使用

创建
CreateThread(NULL, 0, thread_func, NULL, 0, &thread_id);

我在这里没有想法,有什么建议吗?

编辑: 运行以下序列时:

Main_thread:
CreateFile
Write
Close
CreateThread
WaitForThread

Thread_B:
CreateFile
Write
Close

Main_Thread成功,Thread_B没有成功。但是,在编写小数据集时,这样可以正常工作。可能这是因为Thread_B没有继承所有Main_Thread的访问权限?

EDIT2: 这里有很多好的想法,非常感谢!经过一些关于这个问题的工作后,似乎就是这样:

api包含一个Queue-thread,处理所有进出设备的包。该线程处理指向包对象的指针。当指针到达队列的前面时,调用“send_and_get”函数。如果包中的数组是在调用“send_and_get”函数的同一个线程中分配的,那么一切正常。如果在某个其他线程中分配了数组,则发送失败。但是,如何解决这个问题,我不知道。

4 个答案:

答案 0 :(得分:3)

根据winerror,Win32错误998是以下本机状态值之一(将由操作系统或驱动程序返回):

   998 ERROR_NOACCESS <--> 0x80000002 STATUS_DATATYPE_MISALIGNMENT
   998 ERROR_NOACCESS <--> 0xc0000005 STATUS_ACCESS_VIOLATION
   998 ERROR_NOACCESS <--> 0xc00002c5 STATUS_DATATYPE_MISALIGNMENT_ERROR

访问冲突可能是一个可能的候选人,基于你说,“当试图写多个元素时。”你确定你发送的缓冲区足够大吗?

对齐错误非常奇特,但如果设备有一些对齐要求并且开发人员选择使用这些特定错误,则可能是相关的。

-Scott

答案 1 :(得分:2)

仍然听起来像是并发访问。 写入此设备的单独线程需要使用互斥锁或类似工具正确保护对文件的访问。打开主螺纹中的手柄并将其打开或保护整个打开 - &gt;写 - &gt;每个线程中可能出现的关闭序列(使用互斥锁)。

答案 2 :(得分:1)

作为调试措施,由于它是您自己的驱动程序,您可以让驱动程序将其正在接收的请求记录到事件日志中。设置两个相同的测试运行,除了一个运行主线程中的所有代码,另一个运行第二个线程中的所有代码。比较结果可以让您更好地了解正在发生的事情。

让驱动程序报告它返回操作系统的任何错误代码也是一个好主意。

答案 3 :(得分:1)

首先要检查的是,即使在请求到达驱动程序之前,驱动程序或内核模式I / O管理器(负责启动IRP并调用驱动程序)报告的错误(998) 。您应该能够发现这一点,因为这是您的驱动程序。只需记录对驱动程序的Dispatch例程的调用,它返回的内容,它的作用(它是否调用其他驱动程序或使用错误代码调用IoCompleteRequest等)并且事情应该变得清晰。

从您描述的场景中,似乎很可能是错误是由您的驱动程序引起的。例如,您的驱动程序可能会对CreateFile(驱动程序的IRP_MJ_CREATE)的响应分配一些全局状态结构,并在文件关闭时清除它。如果同时打开两个文件,则这样的驱动程序将无法正常运行,然后一个文件被关闭,而第二个文件仍然接收I / O请求。