首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >共享内存未更新

共享内存未更新
EN

Stack Overflow用户
提问于 2013-10-28 14:02:40
回答 1查看 1.6K关注 0票数 2

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

代码语言:javascript
复制
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

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

代码语言:javascript
复制
*m_pDataPtr = some_value;
SetEvent(m_hEventDone);

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

代码语言:javascript
复制
if ( WaitForSingleObject(m_hEventDone, TIMEOUT_INTERVAL) != WAIT_OBJECT_0 )
{
     // handle error and return
}

int result = *m_pDataPtr;

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

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-28 21:55:56

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

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

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19636824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档