Sharing
Memory Between Processes
It is possible to share memory between processes. Once one process has
set up a region of memory with suitable sharing attributes, another process can
open that region of memory and map it into its address space.
Shared memory uses the file mapping function CreateFileMapping() with param-eter INVALID_HANDLE_VALUE to
create a handle to a region of shared memory. This can then be mapped into the
process with a call to MapViewOfFile(). The
steps for attach-ing to an existing region of shared memory are similar, except
that the function OpenFileMapping() is used
to obtain the handle.
The call to CreateFileMapping() takes six parameters, as shown in Table 6.5.
Table 6.5 Parameters
Passed to CreateFileMapping()
An object can be shared between processes either by sharing the object’s
handle, which will be discussed in the section “Inheriting Handles in Child
Processes,” or by using a common name. The name can contain any character
except a backslash and must start with either the global namespace identifier Global\ or the local namespace identi-fier Local\. The global namespace is shared by all users, whereas the local
namespace is private to each user.
The OpenFileMapping() call
that opens an existing file mapping object takes three parameters. The first
parameter gives the security attributes for the mapping object, which usually
will be FILE_MAP_ALL_ACCESS to allow
both reading and writing to the shared memory. The second parameter is a
boolean that determines whether the handle can be inherited by child processes.
The third parameter is the name of the mapping object.
Although the CreateFileMapping() call
creates the mapping object in the kernel, it does not actually map the object
into user space. The call to MapViewOfFile() causes
the shared object to be mapped into memory. The return value of this call is a
pointer to the base address of the memory. This call takes five parameters, as
shown in Table 6.6.
Table 6.6 Parameters
Passed to MapViewOfFile()
The third and fourth parameters are the high-order
and low-order DWORDs of an offset into the shared memory. This will be returned
as the base address of the pointer. In general, the required offset into the
shared memory will be zero, so both of these param-eters will also be zero.
Once the process has finished with the shared
memory, it needs to be unmapped with a call to UnmapViewOfFile(), which takes the base address of the shared memory as a parameter, and
then the handle can be closed with a call to CloseHandle().
The example in Listing 6.27 shows how a region of
memory can be created and then shared between two processes. If the application
is started without any parameters, it will create a child process. The parent
process will also create a region of shared memory and store a string into the
shared memory. The shared memory is given the name shared-memory
and is created in the Local\ namespace. Hence, it is visible to all the processes
owned by the user.
Listing 6.27 Creating
and Using Shared Memory
#include
<Windows.h>
#include
<Windows.h>
int
_tmain(int argc, _TCHAR* argv[])
{
STARTUPINFO startup_info;
PROCESS_INFORMATION process_info;
HANDLE filehandle;
TCHAR ID[] = TEXT("Local\\sharedmemory");
char* memory;
if (argc==1)
{
filehandle =
CreateFileMapping( INVALID_HANDLE_VALUE,
NULL, PAGE_READWRITE, 0, 1024, ID);
memory =
(char*)MapViewOfFile( filehandle, FILE_MAP_ALL_ACCESS,
0, 0, 0 );
sprintf_s( memory, 1024,
"%s", "Data from first process" ); printf( "First
process: %s\n", memory );
ZeroMemory( &process_info, sizeof(process_info)
); ZeroMemory( &startup_info, sizeof(startup_info) ); startup_info.cb =
sizeof(startup_info);
wchar_t commandline[256];
wsprintf( commandline, L"\"%s\" Child\n", argv[0] );
CreateProcessW( argv[0], commandline,
0, 0, 0, 0, 0, 0, &startup_info, &process_info );
WaitForSingleObject(process_info.hProcess,INFINITE);
UnmapViewOfFile(
memory );
CloseHandle(
filehandle );
}
else
{
filehandle =
OpenFileMapping( FILE_MAP_ALL_ACCESS, 0, ID ); memory = (char*)MapViewOfFile(
filehandle, FILE_MAP_ALL_ACCESS,
0, 0, 0 );
printf( "Second process: %s\n", memory );
UnmapViewOfFile(
memory );
CloseHandle(
filehandle );
}
getchar(); return 0;
}
The child process attaches to the shared memory and
can print out the value of the string stored there by the parent process. One
the child process has printed this string, it unmaps the memory and closes the
file handle before exiting. Once the child process has exited, the parent
process is free to unmap the memory, close the file handle, and exit.
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.