gpt4 book ai didi

c - 共享内存未更新

转载 作者:太空宇宙 更新时间:2023-11-03 23:29:15 27 4
gpt4 key购买 nike

我有两个进程,使用内存映射文件和命名事件相互通信。初始化代码在两个进程中是相同的。此处未显示错误处理,但我检查了所有返回值。

HANDLE m_hFileMapping;
LPVOID m_pViewOfFile;
int* m_pDataPtr;
HANDLE m_hEventDone;

m_hFileMapping = CreateFileMapping(
INVALID_HANDLE_VALUE, // system paging file
NULL, // security attributes
PAGE_READWRITE, // protection
0, // high-order DWORD of size
MEMORY_MAPPED_FILE_SIZE, // low-order DWORD of size (4096)
MEMORY_MAPPED_FILE_NAME); // name (the same for both processes)


m_pViewOfFile = MapViewOfFile(
m_hFileMapping, // handle to file-mapping object
FILE_MAP_ALL_ACCESS, // desired access
0,
0,
0); // map all file

m_pDataPtr = (int*)m_pViewOfFile;

m_hEventDone = CreateEvent(NULL, FALSE, FALSE, EVENT_NAME_COMMAND_DONE); // the same name in both processes

服务器进程更新共享内存并设置事件:

*m_pDataPtr = some_value;
SetEvent(m_hEventDone);

客户端进程等待 m_hEventDone。设置事件后,它会读取内存:

if ( WaitForSingleObject(m_hEventDone, TIMEOUT_INTERVAL) != WAIT_OBJECT_0 )
{
// handle error and return
}

int result = *m_pDataPtr;

有时客户端进程从 m_pDataPtr 中读取一个旧的(以前的)值。在下一次迭代中,它可以读取更新的值。两个程序都处于调试配置中,没有优化。它们在 Windows 7 多核计算机上运行。对共享内存的访问是不同步的,因为读/写事务是由用户命令启动并序列化的。

如何更改此程序以在客户端获取最新的更新值?

最佳答案

编译器可以在不改变观察到的行为的情况下优化代码。它通过分析手头的代码来做到这一点。如果推断出它们不相关,则可以自由发出在寄存器中缓存值的指令或重新排序指令。只要编译器看到对内存的所有访问,这就是安全的。

在内存可能以不寻常方式改变的环境中,编译器无法知道。例如硬件寄存器访问或 I/O 映射内存位置,其中内存可以在编译器看到的程序之外更改。为了防止编译器对对象做出任何假设 volatile关键字在 C 和 C++ 中可用。结果是编译器在访问对象时不会执行任何优化或重新排序指令。

要解决您的问题,您必须将驻留在共享内存中的所有数据标记为volatile。这保证了两个进程将始终看到相同的数据。它还确保对象的值在赋值时立即写入。

关于c - 共享内存未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19636824/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com