INTER PROCESS COMMUNICATION-FILE MAPPING/MEMORY MAPPED FILES
This article explains about how to create and use memory
mapped files called "File Mapping" in windows environment. File mapping can be
used to share a file or memory between different processors in windows
environment. Windows provides 32 bit API for accomplishing this task. The
advantage of File mapping is inter process communication and speeding file
access. APIs used for File mapping are CreateFile, ReadFile,
WriteFile, CreateFileMapping, MapViewOfFile,
UnmapViewOfFile, FlushViewOfFile. Example 1 explains how to write
data to File mapping and Example 2 explains how to read data from File
Mapping.
Example 1 starts with checking for command line
arguments. The first argument is File Mapping write executable name and second
argument is the File mapping file name and calls CreateFile for creating
a file. The permissions given are read and write with create always option. It
then calls CreateFileMapping to create the mapping. In this we are
passing the size of memory mapped file and name of the memory mapped file. Using
this memory mapped file object, other process can use for read/write operations.
MapViewOfFile loads the file data into the memory space of the process
and returns the new address of the data. Here we are casting the data to
MEMORYDATA structure(mdata). The mdata will be filled integer values from 0 to
MAXDATA.
Example 2 starts with checking for command line
arguments. The first argument is File Mapping read executable name and second
argument is the File mapping file name and calls CreateFile for opening
an existing file. The permissions given are read option. It then calls
CreateFileMapping to for mapping. In this we are passing the size of memory
mapped file as 0 and name of the memory mapped file. MapViewOfFile loads
the file data into the memory space of the process and returns the new address
of the data. Here we are casting the data to MEMORYDATA structure(mdata). The
values in the mdata will be printed on console.
FlushViewOfFile can be used to flush the changes to
the disk. The system will write to disk only those memory pages that actually
contain modified data.
|
Sample:
The following sample explains how to communicate between two
process in windows environment. One application writes data into file mapping
and another application reads data from file.
File mapping write process example1:
//FileMappingWrite.cpp
#include "windows.h"
#include "iostream.h"
#define MAXMEMORY 1000
struct MEMORYDATA
{
int data[MAXMEMORY];
};
void DisplayError()
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
cout << (LPCTSTR)lpMsgBuf << endl;
LocalFree( lpMsgBuf );
}
int main(int argc, char* argv[])
{
HANDLE fileHandle;
HANDLE mapFileHandle;
struct MEMORYDATA *mdata = NULL;
if(argc <2 || argc > 2)
{
cout << "FileMappingWrite <filename>" <<endl;
return 0;
}
fileHandle = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
CREATE_ALWAYS, 0, 0);
if(fileHandle == INVALID_HANDLE_VALUE)
{
cout << "Unable to create file, Error number " << endl;
DisplayError();
return 0;
}
mapFileHandle = CreateFileMapping(fileHandle , 0, PAGE_READWRITE,
0,sizeof(struct MEMORYDATA), "TEST");
if(mapFileHandle <= 0)
{
cout << "Unable to create file mapping, Error number " << endl;
DisplayError();
return 0;
}
mdata = (struct MEMORYDATA*)MapViewOfFile(mapFileHandle, FILE_MAP_WRITE, 0,
0,0);
for(int i=0;i<MAXMEMORY;i++)
{
mdata->data[i] = i;
Sleep(100);
}
if(!UnmapViewOfFile(mdata))
{
cout << "unable to unmap" << endl;
DisplayError();
}
CloseHandle(mapFileHandle);
CloseHandle(fileHandle);
return 0;
}
File mapping read process example2:
//FileMappingRead.cpp
#include "windows.h"
#include "iostream.h"
#define MAXMEMORY 1000
struct MEMORYDATA
{
int data[MAXMEMORY];
};
void DisplayError()
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
cout << (LPCTSTR)lpMsgBuf << endl;
LocalFree( lpMsgBuf );
}
int main(int argc, char* argv[])
{
HANDLE fileHandle;
HANDLE mapFileHandle;
struct MEMORYDATA *mdata = NULL;
if(argc <2 || argc > 2)
{
cout << "FileMappingRead <filename>" <<endl;
return 0;
}
fileHandle = CreateFile(argv[1], GENERIC_READ , FILE_SHARE_READ |
FILE_SHARE_WRITE, 0,
OPEN_EXISTING, 0, 0);
if(fileHandle == INVALID_HANDLE_VALUE)
{
cout << "Unable to open file, Error number " << endl;
DisplayError();
return 0;
}
mapFileHandle = CreateFileMapping(fileHandle , 0, PAGE_READONLY, 0,0,
"TEST");
if(mapFileHandle <= 0)
{
cout << "Unable to open file mapping, Error number " << endl;
DisplayError();
return 0;
}
mdata = (struct MEMORYDATA*)MapViewOfFile(mapFileHandle, FILE_MAP_READ, 0,
0,0);
cout << "file mapping read data is " << endl;
for(int i=0;i<MAXMEMORY;i++)
{
cout << mdata->data[i] << endl;
Sleep(100);
}
if(!UnmapViewOfFile(mdata))
{
cout << "unable to unmap" << endl;
DisplayError();
}
CloseHandle(mapFileHandle);
CloseHandle(fileHandle);
return 0;
}
|
INTER PROCESS COMMUNICATION-SHARED MEMORY (UNIX/Linux
environment)
Send your comments or feedback to
raoavm@yahoo.com or
avmrao@indiatimes.com
example3:
#include<sys/shm.h>
#include<types.h>
#include<stdio.h>
#define MAXDATA 1000
struct MEMORYDATA
{
int data[MAXDATA];
};
main()
{
int shmid;
key_t key = 0x1025;
int i=0;
struct MEMORYDATA *mdata = NULL;
shmid = shmget(key, sizeof(struct MEMORYDATA),
IPC_CREAT | 0666);
if(shmid < 0)
{
perror("shmget failed");
return 0;
}
mdata = (struct MEMORYDATA*)shmat(shmid,0,0);
if(mdata == NULL)
{
perror("shmat failed");
return 0;
}
for(i=0;i<MAXDATA;i++)
{
mdata->data[i] = i;
}
shmdt(mdata);
}
Example4:
#include<sys/shm.h>
#include<types.h>
#include<stdio.h>
#defie MAXDATA 1000
struct MEMORYDATA
{
int data[MAXDATA];
};
main()
{
int shmidl
key_t key = 0x1025;
int i=0;
struct MEMORYDATA *mdata = NULL;
shmid = shmget(key, sizeof(struct MEMORYDATA),
IPC_CREAT | 0666);
if(shmid < 0)
{
perror("shmget failed");
return 0;
}
mdata = (struct MEMORYDATA*)shmat(shmid,0,0);
if(mdata == NULL)
{
perror("shmat failed");
return 0;
}
for(i=0;i<MAXDATA;i++)
{
printf("%d\n",mdata->data[i]);
}
shmdt(mdata);
}
Example 3 writes the data in shared memory and Example 4
reads the data from shared memory.
|