使用线程时Windows WriteFile问题
Windows WriteFile problem when using threads
我的公司正在开发一种需要与软件通信的硬件。为此,我们制作了一个驱动程序,可以对硬件进行读写。要访问驱动程序,我们使用命令:
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(device),用于关闭文件。
这在从主线程调用函数的情况下工作得很好。如果从其他线程调用它们,则在尝试写入多个元素时得到错误998 (no_access)。使用
创建线程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"函数的同一个线程中分配的,则一切正常。如果数组是在其他线程中分配的,则发送失败。
根据winerror, Win32错误998是以下本机状态值之一(由O/S或驱动程序返回):
998 ERROR_NOACCESS <--> 0x80000002 STATUS_DATATYPE_MISALIGNMENT
998 ERROR_NOACCESS <--> 0xc0000005 STATUS_ACCESS_VIOLATION
998 ERROR_NOACCESS <--> 0xc00002c5 STATUS_DATATYPE_MISALIGNMENT_ERROR
访问冲突可能是一个可能的候选者,基于您所说的"当试图写入多个元素时"。您确定要发送的缓冲区足够大吗?
对齐错误是相当奇特的,但如果设备有一些对齐要求,并且开发人员选择使用这些特定的错误,则可能相关。
斯科特
听起来还是像并发访问。写此设备的单独线程需要使用互斥锁或类似的方法来正确保护对文件的访问。要么在主线程中打开句柄并保持打开状态,要么保护每个线程中可能发生的整个open -> Write -> Close序列(使用互斥锁)。
作为调试措施,因为它是您自己的驱动程序,您可以让驱动程序记录它正在接收的请求,例如,记录到事件日志中。设置两个相同的测试运行,除了一个在主线程中运行所有代码,另一个在第二个线程中运行所有代码。比较结果可以让你更好地了解发生了什么。
让您的驱动程序报告它返回到操作系统的任何错误代码也是一个好主意。
您应该检查的第一件事是,在请求到达您的驱动程序之前,您的驱动程序或内核模式I/O管理器(负责启动IRP并调用您的驱动程序)是否报告了错误(998)。您应该能够发现这一点,因为这是您的驱动程序。只需记录对驱动程序的调度例程的调用,它返回什么,它做了什么(它是否调用其他驱动程序或调用带有错误代码的IoCompleteRequest
等),事情就会变得清晰起来。
从你描述的场景来看,似乎最有可能的错误是由你的驱动程序引起的。例如,您的驱动程序可能在响应CreateFile
(这是驱动程序的IRP_MJ_CREATE
)时分配一些全局状态结构,并在文件关闭时清除它。如果同时打开两个文件,然后关闭一个文件,而另一个文件仍然接收I/O请求,那么这样的驱动程序将无法正常工作。
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- 基于boost的程序的静态链接——zlib问题
- C++格式化输出问题
- 使用线程时Windows WriteFile问题