share_mem.txt
资源名称:share_mem.zip [点击查看]
上传用户:hltzqc
上传日期:2007-01-01
资源大小:2k
文件大小:5k
源码类别:
系统编程
开发平台:
Visual C++
- Server
- Server should create (during initialization) a named file mapping object whose size is defined by the project requirement. Name of the file mapping object should not be something obvious otherwise there is a possibility that it already exists. Also, take care what happens if it is allowed to start multiple instances of the server. For the purpose of this article, it is assumed that only one instance of the server is allowed to be started at any time. After creating a name file mapping object, server should map a view to this object in order to obtain a pointer to the shared memory for further use.
- struct TSharedMemory {
- // Programmer defined structure (project specific)
- };
- TSharedMemory *Msg;
- HANDLE hmem = ::CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,
- sizeof(TSharedMemory),"ApplicationSpecificFileMappingName");
- Msg = (TSharedMemory*)::MapViewOfFile(hmem,FILE_MAP_WRITE,0,0,sizeof(TSharedMemory));
- Besides shared memory, server must also create two named event objects. These events are used by the client to trigger the server to process client data (HExec) and by the server to indicate to the client that data are processed and answer is ready for the client (HDone).
- HANDLE HExec = ::CreateEvent(NULL,FALSE,FALSE,"ApplicationSpecificEventExec");
- HANDLE HDone = ::CreateEvent(NULL,FALSE,FALSE,"ApplicationSpecificEventDone");
- Server should allocate a separate background thread for communication with the clients. Thread executive function should be (pseudo-code):
- while (TRUE) {
- // Timeout is 1 second but can be anything else
- retcode = ::WaitForMultipleObjects(HExec and local event EKillThread, 1000);
- if (retcode is WAIT_TIMEOUT) {
- // Handle timeout if needed
- } else if (retcode is EKillThread) {
- // Kill thread
- break;
- } else if (retcode is HExec) {
- // Client signalled that data in shared memory is ready
- // Handle data, set answer to the client (all via Msg pointer to shared memory)
- ::SetEvent(HDone);
- }
- };
- Basically, thread is waiting for the event HExec to be signalled (this is done by the client after the shared memory is filled with data). Server processes data, places its own answer into the shared memory and triggers the client by signalling the event HDone.
- Client
- Client is started after the server. During initialization, client should open a file mapping object created by the server and map a view to this object to obtain a pointer for local use:
- HANDLE hmem = ::OpenFileMapping(FILE_MAP_WRITE,FALSE,"ApplicationSpecificFileMappingName");
- if (hmem)
- Msg = (TSharedMemory*)::MapViewOfFile(hmem,FILE_MAP_WRITE,0,0,sizeof(TSharedMemory));
- When the client is finished, it should unmap a view to a file and close a handle obtained with ::OpenFileMapping().
- ::UnmapViewOfFile((LPVOID)Msg);
- ::CloseHandle(hmem);
- Client must also create several named event objects and a named mutex object. Mutex HFree is created by each client. This mutex is used to synchronize access to the shared memory among the active clients. Using this mutex, only one client can access the shared memory at any time. Two events are already created by the server so that client will actually get a handle to already existing event. As described before, these two events are used for communication between the client who has access to the shared memory and the server.
- HANDLE HFree = ::CreateMutex(NULL,FALSE,"ApplicationSpecificEventFree");
- HANDLE HExec = ::CreateEvent(NULL,FALSE,FALSE,"ApplicationSpecificEventExec");
- HANDLE HDone = ::CreateEvent(NULL,FALSE,FALSE,"ApplicationSpecificEventExec");
- Client does not have to allocate a thread for communication with the server since this communication is always initiated by the client. However, if the communication to the server is performed from the main application thread, it can compromise the performance of the application since the thread is blocked until the complete communication session with the server is finished. The following pseudo-code describes how to communicate with the server.
- retcode = 1;
- if (::WaitForSingleObject(HFree,250) == WAIT_OBJECT_0) {
- // Fill a shared memory with data using Msg pointer
- .....
- // Signal Server to process this request
- ::SetEvent(HExec);
- if (::WaitForSingleObject(HDone,250) == WAIT_TIMEOUT) {
- retcode = 1;
- }
- // Server finished processing data
- // Handle data returned by the Server
- // Release mutex for others to send messages
- ::ReleaseMutex(HFree);
- retcode = 0;
- }
- return retcode;