如果从其他线程访问(读/写)src缓冲区,是否有可能从memcpy获得访问冲突

Is there any chance to get access violation from memcpy, if src buffer is accessed(read/write) from other thread

本文关键字:是否 缓冲区 有可能 访问冲突 src memcpy 访问 线程 其他 如果      更新时间:2023-10-16

我的应用程序违反了访问问题。

调用堆栈:

0da0ccfc 77c46fa3 ntdll!KiUserExceptionDispatcher+0xe 
0da0d004 4dfeee3a msvcrt!memcpy+0x33 
0da0d45c 4dfdbc4b MyLibrary!MyClass::MyFunc+0x8d [MyFile.cpp @ 574]
[MyFile.cpp @ 574 memcpy( m_pMyPointer, m_pSrcPointer, m_nDataSize);

在这里,我确定以下内容..m_pMyPointer是有效的,任何其他线程都不会读取或写入此内存。m_pMyPointer的大小大于 m_nDataSize。m_pSrcPointer可以从其他线程(读取或写入)访问,m_pSrcPointer的大小小于m_nDataSize的可能性很小。

我的疑问是,如果任何其他线程试图读取/写入m_pSrcPointer,是否有任何理由从memcpy(m_pMyPointer,m_pSrcPointer,m_nDataSize)获得访问违规。由于memcpy()读取m_pSrcPointer,而不是写入它。

我会排除这一点。根据定义,对内存区域的并发读取访问是线程安全的。当一个线程写入另一个线程读取的内存位置时,您将失去线程安全,因为结果是不可预测的,但您仍然不应该遇到访问冲突(在大多数健全的平台中,包括 x86)。

最有可能的是,m_pMyPointerm_pSrcPointer指向的有效内存区域的大小小于 m_nDataSize

但是,如果您怀疑同一块内存是否同时由不同的线程读取和写入,则意味着您至少缺少锁定方案。

如果并发线程仅更改缓冲区中的数据,则不应通过从缓冲区复制/复制到缓冲区来获取任何 AV。

如果并发线程更改指向缓冲区的指针或包含缓冲区大小(字节数或元素数)的变量,则可以使用这些指针和大小变量通过复制到缓冲区或从缓冲区复制轻松获取 AV。在这里,你进入了未定义行为的领域。

可能性很小。如果写入m_srcPtr不是原子的,或者另一个线程正在写入其他成员之一,而您还没有告诉我们(例如,m_nDataSize听起来像是可能的事情)。

如果写入m_srcPtr不是原子的,则根据您的体系结构,在对指针的 2 次写入之间可能会暂时有一个无效的指针。如果m_nDataSize与m_srcPtr"同时"更新,那么您就有很多机会发生不好的事情。

请注意,这是高度依赖于体系结构的。