// 使用Memory Mapping file共享数据,使用一个Event作为并发控制。
// 仅为练习使用。
#define BUFFER_SIZE (100*1024)
#define BUFSIZE 1024
struct BufferStruct
{
BOOL hasRead;
TCHAR buf[512];
};
void CEDSInstallMain1Dlg::OnBnClickedButton1()
{
TCHAR szMapFileName[] = _T("Local\\TestHelloWorld");
// Create the file mapping object
HANDLE hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // Use paging file instead of existing file. // Pass file handle to share in a file.
NULL, // Default security
PAGE_READWRITE, // Read/write access
0, // Max. object size
BUFFER_SIZE, // Buffer size
szMapFileName // Name of mapping object
);
if (hMapFile == NULL)
return;
// Create file view from the file mapping object.
BufferStruct* pBuf = (BufferStruct*) MapViewOfFile(
hMapFile, // Handle of the map object
FILE_MAP_ALL_ACCESS, // Read/write permission
0, // A high-order DWORD of the file offset where the view begins.
0, // A low-order DWORD of the file offset where the view is to begin.
BUFFER_SIZE // The number of bytes of a file mapping to map to the view.
);
if (pBuf == NULL)
{
CloseHandle(hMapFile);
return;
}
pBuf->hasRead = TRUE;
PROCESS_INFORMATION pi[3];
for (int i = 0; i< 3; i++)
{
STARTUPINFO si;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
//si.dwFlags = STARTF_USESHOWWINDOW;
//si.wShowWindow = SW_HIDE;
ZeroMemory(&pi, sizeof(pi));
CString cmdstr;
cmdstr.Format("C:\\Work\\EDSInstall\\Release\\EDSInstall.exe");
// Start the child process.
if(!CreateProcess(NULL, // No module name (use command line)
cmdstr.GetBuffer(0), // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi[i] ) // Pointer to PROCESS_INFORMATION structure
)
{
AfxMessageBox("CreateProcess failed (%d).");
return;
}
}
HANDLE globalEvent = CreateEvent(0, TRUE, FALSE, TEXT("GlobalTestEvent"));
SetEvent(globalEvent);
Sleep(2000);
do
{
DWORD dwRet = WaitForSingleObject(globalEvent, 100);
if (dwRet == WAIT_OBJECT_0)
{
if (pBuf && !pBuf->hasRead)
{
CString msgFromGlobal = pBuf->buf;
// *********************william test*************12/23/2009 1:40:44 PM
TCHAR bufferWill[512];
_stprintf(bufferWill, TEXT(" [%s] BEGIN read: %s ##[%p]L%d\n"), __FUNCTION__,
msgFromGlobal, this, __LINE__);
::OutputDebugString(bufferWill);
// **********************************************/
memset(pBuf->buf, 0, sizeof(TCHAR) * 512);
pBuf->hasRead = TRUE;
SetEvent(globalEvent);
// it is equal to do something.
Sleep(500);
}
else
{
SetEvent(globalEvent);
// wait the data written.
Sleep(500);
}
}
else
{
Sleep(500);
}
} while (1);
AfxMessageBox("finished");
for (int i = 0; i< 3; i++)
{
// Close process and thread handles.
CloseHandle( pi[i].hProcess );
CloseHandle( pi[i].hThread );
}
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
CloseHandle(globalEvent);
}
In the client side:
// *********************william test*************12/23/2009 2:24:20 PM
TCHAR bufferWill[512];
_stprintf(bufferWill, TEXT(" [%s] BEGIN ##L%d\n"), __FUNCTION__,
__LINE__);
::OutputDebugString(bufferWill);
// **********************************************/
TCHAR szMapFileName[] = _T("Local\\TestHelloWorld");
// Create the file mapping object
HANDLE hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // Use paging file instead of existing file. // Pass file handle to share in a file.
NULL, // Default security
PAGE_READWRITE, // Read/write access
0, // Max. object size
BUFFER_SIZE, // Buffer size
szMapFileName // Name of mapping object
);
if (hMapFile == NULL)
return nRetCode;
// Create file view from the file mapping object.
BufferStruct* pBuf = (BufferStruct*) MapViewOfFile(
hMapFile, // Handle of the map object
FILE_MAP_ALL_ACCESS, // Read/write permission
0, // A high-order DWORD of the file offset where the view begins.
0, // A low-order DWORD of the file offset where the view is to begin.
BUFFER_SIZE // The number of bytes of a file mapping to map to the view.
);
if (pBuf == NULL)
{
CloseHandle(hMapFile);
return nRetCode;
}
// *********************william test*************12/23/2009 2:24:20 PM
_stprintf(bufferWill, TEXT(" [%s] step1 ##L%d\n"), __FUNCTION__,
__LINE__);
::OutputDebugString(bufferWill);
// **********************************************/
HANDLE globalEvent = CreateEvent(0, TRUE, FALSE, TEXT("GlobalTestEvent"));
// *********************william test*************12/23/2009 2:24:20 PM
_stprintf(bufferWill, TEXT(" [%s] step2 %X %X ##L%d\n"), __FUNCTION__,
GetCurrentProcessId(), globalEvent, __LINE__);
::OutputDebugString(bufferWill);
// **********************************************/
do
{
DWORD dwRet = WaitForSingleObject(globalEvent, 200);
if (dwRet == WAIT_OBJECT_0)
{
if (pBuf && pBuf->hasRead)
{
CString str;
str.Format("String from sub %X", GetCurrentProcessId());
// Write the message to the file view.
int cbMessageBytes = (str.GetLength() + 1 /* NULL */) * sizeof(TCHAR);
CopyMemory((PVOID)pBuf->buf, str.GetBuffer(0), cbMessageBytes);
// *********************william test*************12/23/2009 2:24:20 PM
_stprintf(bufferWill, TEXT(" [%s] step-loop2 Write: %X ##L%d\n"), __FUNCTION__,
GetCurrentProcessId(), __LINE__);
::OutputDebugString(bufferWill);
// **********************************************/
pBuf->hasRead = FALSE;
SetEvent(globalEvent);
// it is equal to do something.
Sleep(800);
}
else
{
SetEvent(globalEvent);
// wait the data written.
Sleep(500);
}
}
else
{
Sleep(500);
}
} while (1);
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
CloseHandle(globalEvent);