[header.htm]
Process Synchronization Comparison

Shared memory allows fast communications between two processes on same machine
This returns a HANDLE to the mapped file
This returns a pointer to the view of the mapped file.
used for two processes to share memory
This returns a HANDLE to the mapped file
(source code here for producer)
//*************************************************************** // illustrates two processes cooperating in a producer/consumer relationship // This code demonstrates the parent side of handle inheritance. // The producer/consumer relationship is managed by two semaphores // EMPTY and FULL, When EMPTY the producer can produce into empty buffer, // when FULL the consumer can consume buffer. // Buffers are passed through shared memory implemented as a memory mapped file // AUTHOR: Chris Wild // DATE: September 10, 1997 //*************************************************************** #include <windows.h> #include <iostream.h> #include <stdlib.h> const int NBUFFERS = 3; // allow 3 buffers for bounded buffertypedef struct{ int bufID; int bufValue; } Buffer;
void main(void) { HANDLE empty, full;
HANDLE mapFileHandle;
Buffer* commonBuffers;
// Create the semaphores empty = CreateSemaphore(0,NBUFFERS,NBUFFERS, "NTcourse.semaphore.empty");
full = CreateSemaphore(0,0,NBUFFERS, "NTcourse.semaphore.full"); cout << "created semaphores\n"; // create in-memory file for Interprocess Communications mapFileHandle = CreateFileMapping(
(HANDLE) 0xFFFFFFFF, // unnamed file maps to virtual memory 0, // security PAGE_READWRITE, // access to file 0, // high word of file size NBUFFERS*sizeof(Buffer), // size of memory mapped area "commonBuffer"); // name it to share with other processes commonBuffers = (Buffer*) MapViewOfFile(mapFileHandle,
FILE_MAP_WRITE, 0, // High offset 0, // Low offest 0); // 0 for mapping entire file // enter a loops producing some things int bufN = 0; for(int i = 0; i < 10; i++) { // First wait for previous resource to be empty (consumed) cout << "PRODUCER: waiting for empty buffer\n"; WaitForSingleObject(empty, INFINITE);
commonBuffers[bufN].bufID = bufN;
commonBuffers[bufN].bufValue = 1000*i; bufN = (bufN+1) % NBUFFERS;
// Have empty resource - use it to produce // put code here to produce something cout << "PRODUCER: producing a new buffer\n"; ReleaseSemaphore(full,1,0); // signals production
} CloseHandle(empty); CloseHandle(full); CloseHandle(mapFileHandle); }
(source code here for consumer)
//...
HANDLE empty, full; // control bounded buffer access
HANDLE mapFileHandle; // used to access the shared
Buffer* commonBuffers; // pointer into memory mapped file to array of buffer structures
cout << "Entered consumer: v2\n";
empty = OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE, "NTcourse.semaphore.empty");
if(empty == NULL) {
cout << "Error opening empty: "
<< GetLastError() << endl;
ExitProcess(1);
}
full = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, "NTcourse.semaphore.full");
if(full == NULL) {
cout << "Error opening full: "
<< GetLastError() << endl;
ExitProcess(1);
}
mapFileHandle = OpenFileMapping(PAGE_READWRITE,
FALSE, // child cannot inherit
"commonBuffer");
if(mapFileHandle == NULL) {
cout << "Error opening commonBuffer: "
<< GetLastError() << endl;
ExitProcess(1);
}
commonBuffers = (Buffer*) MapViewOfFile(mapFileHandle,
FILE_MAP_READ,
0, // High offset
0, // Low offest
0); // 0 for mapping entire file
if(commonBuffers == NULL) {
cout << "Error mapping file: "
<< GetLastError() << endl;
ExitProcess(1);
}
// enter a loops consuming some things
int bufN = 0;
DWORD returnValue;
while(true) {
// First wait for buffer to be produced
cout << "CONSUMER: waiting for full buffer\n";
returnValue = WaitForSingleObject(full, 10000); // wait 10 seconds
if( returnValue == WAIT_TIMEOUT) {
cout << "Waited too long for producer - assumed died\n";
break;
}
// Have full buffer - consume it
cout << "CONSUMER: emptied buffer: " <<
commonBuffers[bufN].bufID <<
" with value: " << commonBuffers[bufN].bufValue << endl;
bufN = (bufN+1) % NBUFFERS;
ReleaseSemaphore(empty,1,0);
// signals empty
}
CloseHandle(empty);
CloseHandle(full);
CloseHandle(mapFileHandle);
}
(source code here for create process producer)
//... STARTUPINFO startUpInfo;PROCESS_INFORMATION procInfo;
BOOL success; char s[100]; // command line arguments (unused in this example)
// . . . GetStartupInfo(&startUpInfo);
// short cut to fill most of the windowing parameters for child environment // Create the child process success=CreateProcess("consumer.exe", s, 0, 0, FALSE,
CREATE_NEW_CONSOLE,
0, 0, &startUpInfo, &procInfo); if (!success) cout << "Error creating process v2: " << GetLastError() << endl; // . . . WaitForSingleObject(procInfo.hProcess, INFINITE);
//. . .
[footer.htm]