2013-10-28 5 views
2

두 개의 프로세스가 있으며, 메모리 매핑 된 파일과 이벤트라는 이름을 사용하여 서로 이야기하고 있습니다. 초기화 코드는 두 프로세스에서 동일합니다. 오류 처리는 여기에 표시되지 않지만 모든 반환 값을 확인합니다.공유 메모리가 업데이트되지 않았습니다.

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 멀티 코어 컴퓨터에서 실행됩니다. 읽기/쓰기 트랜잭션은 사용자 명령에 의해 시작되고 직렬화되기 때문에 공유 메모리에 대한 액세스는 동기화되지 않습니다.

이 프로그램을 어떻게 변경하여 클라이언트 측에서 최신 업데이트 값을 얻을 수 있습니까?

+4

volatile은 컴파일러가 변수 값을 캐시하거나 캐시에서 읽는 것을 방지합니다. 대신 값은 메모리에서 읽습니다. – IInspectable

+0

@IInspectable : 포인터를 volatile로 정의하면 문제가 해결됩니다. 대답을이 글에 게시하면 받아 들일 것입니다. –

답변

2

컴파일러는 관찰 된 동작을 변경하지 않는 방식으로 코드를 최적화 할 수 있습니다. 그것은 바로 코드를 분석함으로써 그렇게합니다. 서로 관련이 없다고 추론하는 경우 레지스터에 값을 캐시하거나 명령을 재정렬하는 명령을 자유롭게 내보낼 수 있습니다. 이것은 컴파일러가 메모리에 대한 모든 액세스를 보는 한 안전합니다.

에서 메모리가 변경 될 수있는 환경에서는 방법으로 컴파일러가 알 수있는 방법이 없습니다. 예를 들어, 하드웨어 레지스터 액세스 또는 I/O 매핑 메모리 위치가 있습니다. 메모리 위치는 컴파일러가 보는 프로그램 외부에서 변경 될 수 있습니다. 컴파일러가 객체에 대한 가정을하지 못하도록 volatile 키워드는 C 및 C++에서 사용할 수 있습니다. 결과적으로 컴파일러는 객체에 액세스 할 때 최적화 또는 순서 변경 명령을 수행하지 않습니다.

문제를 해결하려면 공유 메모리에있는 모든 데이터를 volatile으로 표시해야합니다. 이렇게하면 두 프로세스가 항상 동일한 데이터를 볼 수 있습니다. 또한 객체의 값이 할당시 즉시 기록되도록합니다.

관련 문제