C++简单封装共享内存
来源:互联网 发布:linux多线程进程效率 编辑:程序博客网 时间:2024/06/03 17:35
目前代码只考虑linux环境,win32将随后补充:
Assertx.h
/* * File: Assertx.h * Author: Vicky.H * Email: eclipser@163.com * * Created on 2014年1月16日, 下午8:33 */// 断言#ifndef CN_VICKY__ASSERTX_H#defineCN_VICKY__ASSERTX_H#include <sys/types.h>#include <stdio.h>extern int g_Command_Assert; //控制参数,不提示Assert的对话框,直接忽略extern int g_Command_IgnoreMessageBox; //控制参数,跳过MyMessageBox的中断void __assert__(const char* file, uint line, const char* func, const char* expr);void __assertex__(const char* file, uint line, const char* func, const char* expr, const char* msg);void __assertspecial__(const char* file, uint line, const char* func, const char* expr, const char* msg);void __messagebox__(const char* msg);void __protocol_assert__(const char* file, int line, const char* func, const char* expr);#define Assert(expr) {if(!(expr)){__assert__(__FILE__,__LINE__,__PRETTY_FUNCTION__,#expr);}}#define ProtocolAssert(expr) ((VOID)((expr)?0:(__protocol_assert__(__FILE__,__LINE__,__PRETTY_FUNCTION__,#expr),0)))#define AssertEx(expr,msg) {if(!(expr)){__assertex__(__FILE__,__LINE__,__PRETTY_FUNCTION__,#expr,msg);}}#define AssertSpecial(expr,msg) {if(!(expr)){__assertspecial__(__FILE__,__LINE__,__PRETTY_FUNCTION__,#expr,msg);}}#define AssertExPass(expr,msg) {if(!(expr)){__assertex__(__FILE__,__LINE__,__PRETTY_FUNCTION__,#expr,msg);}}#define MyMessageBox(msg) ((VOID)0)#endif/* CN_VICKY__ASSERTX_H */
Assertx
#include "Assertx.h"#include <time.h>#include <execinfo.h>int g_Command_Assert = 0;// 控制参数,0:会通过弹出对话框让用户选择(缺省值)//1:忽略//2:继续抛出异常用于获取运行堆栈int g_Command_IgnoreMessageBox = false; //控制参数,跳过MyMessageBox的中断void __show__(const char* szTemp) { printf("Assert:%s", szTemp); throw (1);}void __messagebox__(const char*msg) { if (g_Command_IgnoreMessageBox) return;}void __assert__(const char * file, uint line, const char * func, const char * expr) { char szTemp[1024] = {0}; sprintf(szTemp, "[%s][%d][%s][%s]\n", file, line, func, expr); __show__(szTemp);}void __assertex__(const char * file, uint line, const char * func, const char * expr, const char* msg) { char szTemp[1024] = {0}; sprintf(szTemp, "[%s][%d][%s][%s]\n[%s]\n", file, line, func, expr, msg); __show__(szTemp);}void __assertspecial__(const char * file, uint line, const char * func, const char * expr, const char* msg) { char szTemp[1024] = {0}; sprintf(szTemp, "S[%s][%d][%s][%s]\n[%s]\n", file, line, func, expr, msg); __show__(szTemp);}void __protocol_assert__(const char * file, uint line, const char * func, const char * expr) { printf("[%s][%d][%s][%s]", file, line, func, expr);}
Common.h
/* * File: Common.h * Author: Vicky.H * Email: eclipser@163.com * * Created on 2014年1月16日, 下午10:46 */#ifndef CN_VICKY__COMMON_H#defineCN_VICKY__COMMON_H#include "Assertx.h"//无效的ID值#define INVALID_ID -1#define __ENTER_FUNCTION {try{#define __LEAVE_FUNCTION }catch(...){AssertSpecial(false,__PRETTY_FUNCTION__);}}//根据指针值删除内存#ifndef SAFE_DELETE#define SAFE_DELETE(x)if( (x)!=NULL ) { delete (x); (x)=NULL; }#endif//根据指针值删除数组类型内存#ifndef SAFE_DELETE_ARRAY#define SAFE_DELETE_ARRAY(x)if( (x)!=NULL ) { delete[] (x); (x)=NULL; }#endif//根据指针调用free接口#ifndef SAFE_FREE#define SAFE_FREE(x)if( (x)!=NULL ) { free(x); (x)=NULL; }#endif//根据指针调用Release接口#ifndef SAFE_RELEASE#define SAFE_RELEASE(x)if( (x)!=NULL ) { (x)->Release(); (x)=NULL; }#endif#endif/* CN_VICKY__COMMON_H */
log.h
/* * File: Log.h * Author: Vicky.H * Email: eclipser@163.com * * Created on 2014年1月16日, 下午10:45 */#ifndef CN_VICKY__LOG_H#defineCN_VICKY__LOG_H#include <pthread.h>#define SHMEM_LOG_PATH "./Log/ShareMemory.log"extern pthread_mutex_t log_mutex;class Log {public: Log(); ~Log(); //支持异步写入操作的日志写入 static void SaveLog(const char* filename, const char* msg, ...);};#endif/* CN_VICKY__LOG_H */
Log.cpp
#include "Log.h"#include "Common.h"#include <stdarg.h>#include <string.h>#include <stdio.h>// 保证日志记录线程安全pthread_mutex_t log_mutex;Log::Log() {}Log::~Log() {}void Log::SaveLog(const char* filename, const char* msg, ...) { __ENTER_FUNCTION pthread_mutex_lock(&log_mutex); char buffer[2048]; memset(buffer, 0, 2048); va_list argptr; try { va_start(argptr, msg); vsprintf(buffer, msg, argptr); va_end(argptr); FILE* f = fopen(filename, "ab"); fwrite(buffer, 1, strlen(buffer), f); fclose(f); printf(buffer); } catch (...) { printf("a big error here"); } pthread_mutex_unlock(&log_mutex); return; __LEAVE_FUNCTION pthread_mutex_unlock(&log_mutex);}
ShareMemApi.h
/* * File: ShareMemApi.h * Author: Vicky.H * Email: eclipser@163.com * * Created on 2014年1月16日, 下午8:12 */#ifndef CN_VICKY__SHAREMEMAPI_H#defineCN_VICKY__SHAREMEMAPI_H#include "Common.h"typedef int SMHandle;typedef key_t SM_KEY;typedef size_t SM_SIZE;typedef ushort SMUID_t;#define INVALID_SM_HANDLE -1namespace ShareMemAPI { /* * 创建ShareMem 内存区 * 得到一个共享内存标识符或创建一个共享内存对象并返回共享内存标识符 *key 创建ShareMem 的关键值 * Size 创建大小 *返回 对应ShareMem保持值 */ SMHandle CreateShareMem(SM_KEY key, SM_SIZE size); /* * 打开ShareMem 内存区 * key 打开ShareMem 的关键值 * Size 打开大小 * 返回 对应ShareMem 保持值 */ SMHandle OpenShareMem(SM_KEY key, SM_SIZE size); /* * 映射ShareMem 内存区 * 把共享内存区对象映射到调用进程的地址空间,连接共享内存标识符为shmid的共享内存,连接 * 成功后把共享内存区对象映射到调用进程的地址空间,随后可像本地空间一样访问 *handle 映射ShareMem 的保持值 * 返回 ShareMem 的数据指针 */ void* MapShareMem(SMHandle handle); /* * 关闭映射 ShareMem 内存区 * 与shmat函数相反,是用来断开与共享内存附加点的地址,禁止本进程访问此片共享内存 *MemoryPtr ShareMem 的数据指针 * 返回 0成功 -1失败 */ int UnMapShareMem(const void* MemoryPtr); /* * 关闭ShareMem * 完成对共享内存的控制,关闭共享内存(ipcrm -m shmid)。 * handle 需要关闭的ShareMem 保持值 * 返回 0成功 -1失败 */ int CloseShareMem(SMHandle handle);}#endif/* CN_VICKY__SHAREMEMAPI_H */
ShareMemAPI.cpp
#include "ShareMemAPI.h"#include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <errno.h>namespace ShareMemAPI { SMHandle CreateShareMem(SM_KEY key, SM_SIZE size) { __ENTER_FUNCTION //char keybuf[64]; //memset(keybuf,0,64); //sprintf(keybuf,"./%d",key); //key = ftok(keybuf,'w'); SMHandle hd = shmget(key, size, IPC_CREAT | IPC_EXCL | 0666); printf("handle = %d ,key = %d ,error: %d \r\n", hd, key, errno); return hd; __LEAVE_FUNCTION return SMHandle(-1); } SMHandle OpenShareMem(SM_KEY key, SM_SIZE Size) { __ENTER_FUNCTION //char keybuf[64]; //memset(keybuf,0,64); //sprintf(keybuf,"./%d",key); //key = ftok(keybuf,'w'); SMHandle hd = shmget(key, Size, 0); printf("handle = %d ,key = %d ,error: %d \r\n", hd, key, errno); return hd; __LEAVE_FUNCTION return SMHandle(-1); } void* MapShareMem(SMHandle handle) { __ENTER_FUNCTION return shmat(handle, 0, 0); __LEAVE_FUNCTION return 0; } int UnMapShareMem(const void* MemoryPtr) { __ENTER_FUNCTION return shmdt(MemoryPtr); __LEAVE_FUNCTION return -1; } int CloseShareMem(SMHandle handle) { __ENTER_FUNCTION return shmctl(handle, IPC_RMID, 0); __LEAVE_FUNCTION return -1; }}
ShareMemAO.h
/* * File: ShareMemAO.h * Author: Vicky.H * Email: eclipser@163.com * * Created on 2014年1月16日, 下午9:36 */#ifndef CN_VICKY__SHAREMEMAO_H#defineCN_VICKY__SHAREMEMAO_H#include "ShareMemApi.h"// 命令模式enum CMD_MODE { CMD_MODE_GETORCRT = 0, //创建或删除 CMD_MODE_CLEARALL = 1, //清除模式 CMD_MODE_LOADDUMP = 2, //载入dump模式};// 共享内存头结构struct SMHead { SM_KEY m_Key; SM_SIZE m_Size; uint m_HeadVer; //最后存盘版本 SMHead() : m_Key(), m_Size(), m_HeadVer() { }};/* * 共享内存访问对象 * ShareMemoryAccessObject */class ShareMemAO {public: ShareMemAO() : m_pDataPtr(), m_hold(), m_Size(), m_pHeader(), m_CmdArg() { } ~ShareMemAO() { }; /* *创建ShareMem 访问对象(新创建) * SM_KEYkey访问键值 *SM_SIZESize 访问数据区字节个数 */ bool Create(SM_KEY key, SM_SIZE size); /* *销毁对象 */ void Destory(); /* * 附着ShareMem 访问对象(不是新创建) * SM_KEYkey访问键值 *SM_SIZEsize 访问数据区字节个数 */ bool Attach(SM_KEY key, SM_SIZE size); /* *取消附着(不销毁) * // TODO 尚未实现 */ bool Detach(); /* *获得数据区指针 */ void* GetDataPtr() { return m_pDataPtr; } /* *获得 大小为tSize 的第tIndex 个smu的数据 */ void* GetTypePtr(SM_SIZE tSize, SM_SIZE tIndex) { Assert(tSize > 0); Assert(tSize * tIndex < m_Size); if (tSize <= 0 || tIndex >= m_Size) return NULL; return (char*) m_pDataPtr + tSize * tIndex; } /* *获得数据区总大小 */ SM_SIZE GetSize() { return m_Size; } bool DumpToFile(char* FilePath); bool MergeFromFile(char* FilePath); uint GetHeadVer(); void SetHeadVer(uint ver); //命令 int m_CmdArg;private: SM_SIZE m_Size; //ShareMemory内存大小 void* m_pDataPtr; // ShareMemory 数据指针 void* m_pHeader; // ShareMemory内存头指针 SMHandle m_hold; // ShareMemory句柄};#endif/* CN_VICKY__SHAREMEMAO_H */
ShareMemAO.cpp
#include "ShareMemAO.h"#include "Log.h"using namespace ShareMemAPI;bool ShareMemAO::Create(SM_KEY key, SM_SIZE size) { __ENTER_FUNCTION // 判断当前模式 if (m_CmdArg == CMD_MODE_CLEARALL) return false; // 创建指定key和size的共享内存区 m_hold = ShareMemAPI::CreateShareMem(key, size); if (m_hold == INVALID_SM_HANDLE) { Log::SaveLog(SHMEM_LOG_PATH, "Create ShareMem Error SM_KET = %d", key); return false; } // 获得共享内存区的映射指针,起始点 m_pHeader = ShareMemAPI::MapShareMem(m_hold); if (m_pHeader) { // 设置数据开始指针地址,起始点 m_pDataPtr = (char*) m_pHeader + sizeof (SMHead); // 设置Head信息,key 和 size信息 ((SMHead*) m_pHeader)->m_Key = key; ((SMHead*) m_pHeader)->m_Size = size; // 数据块大小 m_Size = size; Log::SaveLog(SHMEM_LOG_PATH, "Create ShareMem Ok SM_KET = %d", key); return true; } else { Log::SaveLog(SHMEM_LOG_PATH, "Map ShareMem Error SM_KET = %d", key); return false; } __LEAVE_FUNCTION return false;}void ShareMemAO::Destory() { __ENTER_FUNCTION if (m_pHeader) { // 关闭共享内存映射 ShareMemAPI::UnMapShareMem(m_pHeader); m_pHeader = 0; } if (m_hold) { // 关闭共享内存区 ShareMemAPI::CloseShareMem(m_hold); m_hold = 0; } m_Size = 0; __LEAVE_FUNCTION}bool ShareMemAO::Attach(SM_KEY key, SM_SIZE size) { __ENTER_FUNCTION // 根据key和size打开共享内存区 m_hold = ShareMemAPI::OpenShareMem(key, size); // 判断命令模式 if (m_CmdArg == CMD_MODE_CLEARALL) { Destory(); // 销毁共享内存区 printf("Close ShareMemory key = %d \r\n", key); return false; } // 打开失败! if (m_hold == INVALID_SM_HANDLE) { Log::SaveLog(SHMEM_LOG_PATH, "Attach ShareMem Error SM_KET = %d", key); return false; } // 映射共享内存区,获得内存块首地址 m_pHeader = ShareMemAPI::MapShareMem(m_hold); if (m_pHeader) { // 设置数据内容开始内存块首地址 m_pDataPtr = (char*) m_pHeader + sizeof (SMHead); // 判断key和size是否与之前创建时一致 Assert(((SMHead*) m_pHeader)->m_Key == key); Assert(((SMHead*) m_pHeader)->m_Size == size); m_Size = size; Log::SaveLog(SHMEM_LOG_PATH, "Attach ShareMem OK SM_KET = %d", key); return true; } else { Log::SaveLog(SHMEM_LOG_PATH, "Map ShareMem Error SM_KET = %d", key); return false; } __LEAVE_FUNCTION return false;}bool ShareMemAO::DumpToFile(char* FilePath) { __ENTER_FUNCTION // 将内存数据写入文本操作 Assert(FilePath); FILE* f = fopen(FilePath, "wb"); if (!f) return false; fwrite(m_pHeader, 1, m_Size, f); fclose(f); return true; __LEAVE_FUNCTION return false;}bool ShareMemAO::MergeFromFile(char* FilePath) { __ENTER_FUNCTION // 将文本数据加载到内存操作 Assert(FilePath); FILE* f = fopen(FilePath, "rb"); if (!f) return false; fseek(f, 0L, SEEK_END); int FileLength = ftell(f); fseek(f, 0L, SEEK_SET); fread(m_pHeader, FileLength, 1, f); fclose(f); return true; __LEAVE_FUNCTION return false;}void ShareMemAO::SetHeadVer(uint ver) { __ENTER_FUNCTION // 版本信息 ((SMHead*) m_pHeader)->m_HeadVer = ver; __LEAVE_FUNCTION}uint ShareMemAO::GetHeadVer() { __ENTER_FUNCTION // 获得版本信息 uint ver = ((SMHead*) m_pHeader)->m_HeadVer; return ver; __LEAVE_FUNCTION return 0;}
SMUManager.h
/* * File: SMUManager.h * Author: Vicky.H * Email: eclipser@163.com * * Created on 2014年1月16日, 下午10:40 */#ifndef CN_VICKY__SMUMANAGER_H#defineCN_VICKY__SMUMANAGER_H#include "ShareMemAO.h"#include "Common.h"#include "Log.h"#include "string.h"// 全局CMD参数extern int g_CmdArgv;// 共享内存池类型enum SMPOOL_TYPE { SMPT_SHAREMEM, // SMPT_SERVER, // 服务器使用的共享内存池 SMPT_WORLD, // 世界服务器使用的共享内存池};//ShareMemory 单元池template<typename T> // T 类型需要包涵成员函数:SetPoolID(uint index), // 并且能通过sizeof(T) 获得其所一个对象最大所占空间。 // 故最好包涵SMUHead属性。class SMUPool {public: SMUPool() : m_pRefObjPtr(), m_hObj(), m_nMaxSize(-1), m_nPosition(-1) { } ~SMUPool() { __ENTER_FUNCTION SAFE_DELETE(m_pRefObjPtr); SAFE_DELETE_ARRAY(m_hObj); __LEAVE_FUNCTION } // 初始化共享内存单元池,分配key,大小为nMaxCount * sizeof(T) + sizeof(SMHead) 的共享内存区 bool Init(uint nMaxCount /*初始化数量*/, SM_KEY key /*标识*/, SMPOOL_TYPE SMPT /*共享内存区类型*/) { __ENTER_FUNCTION // 创建共享内存对象 m_pRefObjPtr = new ShareMemAO(); Assert(m_pRefObjPtr); if (!m_pRefObjPtr) return false; // 设置为全局命令模式 m_pRefObjPtr->m_CmdArg = g_CmdArgv; bool ret; // 打开共享内存区 ret = m_pRefObjPtr->Attach(key, sizeof (T) * nMaxCount + sizeof (SMHead)); if (SMPT == SMPT_SHAREMEM) { if (!ret) { // 打开失败,但类型如果是共SMPT_SHAREMEM,那么新建共享内存区 ret = m_pRefObjPtr->Create(key, sizeof (T) * nMaxCount + sizeof (SMHead)); } } else { if (!ret) { return false; } } if (!ret) { // 如果打开失败,设置命令为删除 if (m_pRefObjPtr->m_CmdArg == CMD_MODE_CLEARALL) { return true; } Log::SaveLog(SHMEM_LOG_PATH, "Setup SMU block fail!"); Assert(ret); return ret; } m_nMaxSize = nMaxCount; m_nPosition = 0; // 创建指向内存池所有T空间的数组 m_hObj = new T* [m_nMaxSize]; int i; for (i = 0; i < m_nMaxSize; i++) { // 初始化数组值 m_hObj[i] = reinterpret_cast<T*> (m_pRefObjPtr->GetTypePtr(sizeof (T), i)); if (m_hObj[i] == NULL) { Assert(m_hObj[i] != NULL); return false; } } m_key = key; return true; __LEAVE_FUNCTION return false; } // 结束,销毁共享内存区 bool Finalize() { __ENTER_FUNCTION Assert(m_pRefObjPtr); m_pRefObjPtr->Destory(); return true; __LEAVE_FUNCTION return false; } // 通过内存池 T* NewObj(void) { __ENTER_FUNCTION Assert(m_nPosition < m_nMaxSize); if (m_nPosition >= m_nMaxSize) { return NULL; } T *pObj = m_hObj[m_nPosition]; // 设置对象在内存池的坐标 pObj->SetPoolID((uint) m_nPosition); // 每分配一个内存单元后,坐标+1 m_nPosition++; return pObj; __LEAVE_FUNCTION return NULL; } // 释放内存单元,可重新使用该内存区。 void DeleteObj(T *pObj) { __ENTER_FUNCTION Assert(pObj != NULL); if (pObj == NULL) { return; } Assert(m_nPosition > 0); if (m_nPosition <= 0) { return; } uint uDelIndex = pObj->GetPoolID(); Assert(uDelIndex < (uint) m_nPosition); if (uDelIndex >= (uint) m_nPosition) { return; } // 将被释放的内存区与内存池最后一个坐标指针交换,设置当前坐标-1 m_nPosition--; T *pDelObj = m_hObj[uDelIndex]; m_hObj[uDelIndex] = m_hObj[m_nPosition]; m_hObj[m_nPosition] = pDelObj; m_hObj[uDelIndex]->SetPoolID(uDelIndex); m_hObj[m_nPosition]->SetPoolID(INVALID_ID); // 设置该内存单元的坐标无效, // 表示尚未被使用,可以通过NewObj() 获得 __LEAVE_FUNCTION } // 获得共享内存池指定区 T* GetPoolObj(int iIndex) { Assert(iIndex < m_nMaxSize); return m_hObj[iIndex]; } // 获得共享内存池大小 int GetPoolMaxSize() { return m_nMaxSize; } // 获得已经使用的大小 int GetPoolSize() { return m_nPosition; } // 获得共享内存区的key SM_KEY GetKey() { return m_key; } // 将共享内存区的数据备份到文件中 bool DumpToFile(char* FilePath) { if (!m_pRefObjPtr) { Assert(m_pRefObjPtr); return false; } return m_pRefObjPtr->DumpToFile(FilePath); } // 将文件数据,加载到共享内存区中 bool MergeFromFile(char* FilePath) { if (!m_pRefObjPtr) { Assert(m_pRefObjPtr); return false; } return m_pRefObjPtr->MergeFromFile(FilePath); } // 获得版本号 uint GetHeadVer() { Assert(m_pRefObjPtr); return m_pRefObjPtr->GetHeadVer(); } // 设置版本号 void SetHeadVer(uint ver) { Assert(m_pRefObjPtr); return m_pRefObjPtr->SetHeadVer(ver); }private: T** m_hObj; //管理对象SMU数组,new T* [m_nMaxSize] int m_nMaxSize; //最大容量,存放T的个数 int m_nPosition; //当前使用偏移 ShareMemAO* m_pRefObjPtr; //引用SMObject,操作类对象 SM_KEY m_key; //对应的ShareMemory Key};#define SM_USE_FREE0#define SM_USE_READYFREE1#define SM_USE_FREEED2#define SM_USE_HOLDDATA3#defineSM_FREE0x00//共享内存空闲#defineSM_C_READ0x01//共享内存自己读取#defineSM_C_WRITE0x02//共享内存自己写#defineSM_S_READ0x03//Server读#defineSM_S_WRITE0x04//Server写#defineSM_W_READ0x05//World 读#defineSM_W_WRITE0x06//World 写struct SMUHead { uint PoolId; SMUID_t SMUid; int UseStatus; char flag; short PID; uint SaveTime; //应该是保存绝对时间, //因为牵涉到不同进程之间通讯 //精确到秒 SMUHead() { CleanUp(); } void CleanUp() { PoolId = -1; SMUid = 0; PID = -1; UseStatus = SM_USE_FREE; flag = SM_FREE; SaveTime = 0; }}; #endif/* CN_VICKY__SMUMANAGER_H */
// 创建测试事例:
User.h
/* * File: User.h * Author: Vicky.H * Email: eclipser@163.com * * Created on 2014年1月17日, 下午1:32 */#ifndef CN_VICKY__USER_H#defineCN_VICKY__USER_H#include <stdio.h>class User {public: User() : username(), password() { } void SetPoolID(uint poolID) { m_SMUHead.PoolId = poolID; } uint GetPoolID() { return m_SMUHead.PoolId; } void SetUsername(const char* username) { strcpy(this->username, username); } const char* GetUsername() const { return this->username; } void SetPassword(const char* password) { strcpy(this->password, password); } const char* GetPassword() const { return this->password; }private: SMUHead m_SMUHead; char username[32]; char password[32];};#endif/* CN_VICKY__USER_H */
ShareMemManager.h
/* * File: ShareMemManager.h * Author: Vicky.H * Email: eclipser@163.com * * Created on 2014年1月17日, 下午3:16 */#ifndef CN_VICKY__SHAREMEMMANAGER_H#defineCN_VICKY__SHAREMEMMANAGER_H#include "SMUManager.h"class User;extern SMUPool<User> g_UserSMUPool;#endif/* CN_VICKY__SHAREMEMMANAGER_H */
main.cpp
/* * File: main.cpp * Author: Vicky.H * Email: eclipser@163.com *///#include "ShareMemApi.h"//#include "ShareMemAO.h"#include "ShareMemManager.h"#include "User.h"#include <unistd.h>#include <iostream>int g_CmdArgv = CMD_MODE_GETORCRT;SMUPool<User> g_UserSMUPool;/* * */int main(void) { // 创建内存共享区// SM_KEY key = 289997171;// SM_SIZE size = 1024 * 1024;// SMHandle m_hold = -1;// m_hold = ShareMemAPI::CreateShareMem(key, size);// if (m_hold == INVALID_SM_HANDLE) {// std::cout << "Create ShareMem Error SM_KET = " << key << std::endl;// return 1;// }// 使用linux命令查看内存共享的情况//[vicky@localhost ~]$ ipcs////------ Shared Memory Segments --------//key shmid owner perms bytes nattch status shmid 0 这是内存区操作的主键,也就是m_hold的值!!//0x11490173 0 vicky 666 1048576 0 // 0x11490173 = 289997171 1048576 = 1024 * 1024////------ Semaphore Arrays --------//key semid owner perms nsems ////------ Message Queues --------//key msqid owner perms used-bytes messages // 取得ipc信息://ipcs [-m|-q|-s]//-m 输出有关共享内存(shared memory)的信息//-q 输出有关信息队列(message queue)的信息//-s 输出有关“遮断器”(semaphore)的信息//%ipcs -m // 删除ipc//ipcrm -m|-q|-s shm_id//ipcrm -m 0 0对应 shmid 也就是m_hold的值 // 程序删除共享内存// ShareMemAPI::CloseShareMem(m_hold); // 操作共享内存区// void* pMemHead = 0;// pMemHead = ShareMemAPI::MapShareMem(m_hold);// std::cout << std::showpoint << pMemHead << std::endl;// strcpy((char*) pMemHead, "hello share memory");// std::cout << "pMemHead : " << (char*)pMemHead << std::endl;// // int result = ShareMemAPI::UnMapShareMem(pMemHead);// std::cout << "result = " << result << std::endl;// std::cout << std::showpoint << pMemHead << std::endl; // 在创建共享内存区,并且操作了共享内存区之后,新进程访问共享内存区 // handle = 262144 ,key = 289997171 ,error: 0 // SMHandle m_hold = -1;// m_hold = ShareMemAPI::OpenShareMem(289997171, 1024 * 1024);// void* pMemHead = 0;// pMemHead = ShareMemAPI::MapShareMem(m_hold);// std::cout << "pMemHead : " << (char*)pMemHead << std::endl;#define USERKEY 10001 std::cout << &g_UserSMUPool << std::endl; std::cout << "\n---------------------------" << std::endl; bool flag; flag = g_UserSMUPool.Init(10, USERKEY, SMPT_SHAREMEM); if (flag) { std::cout << "初始化共享内存池成功!" << std::endl; } else{ std::cout << "初始化共享内存池失败!" << std::endl; } pid_t pid; pid = fork(); if (pid == 0) { // 子进程 std::cout << "\n---------------------------" << std::endl; // 写入数据 User* pUser1 = g_UserSMUPool.NewObj(); if (pUser1) { std::cout << pUser1->GetPoolID() << std::endl; } User* pUser2 = g_UserSMUPool.NewObj(); if (pUser2) { std::cout << pUser2->GetPoolID() << std::endl; } pUser1->SetUsername("u1"); pUser1->SetPassword("p1"); pUser2->SetUsername("u2"); pUser2->SetPassword("p2"); } else if (pid > 0) { // 父进程 std::cout << "\n---------------------------" << std::endl; sleep(5); // 读取数据 User* pUser1 = g_UserSMUPool.GetPoolObj(0); User* pUser2 = g_UserSMUPool.GetPoolObj(1); std::cout << "\n---------------------------" << std::endl; if (pUser1) { std::cout << pUser1->GetUsername() << " " << pUser1->GetPassword() << std::endl; } if (pUser2) { std::cout << pUser2->GetUsername() << " " << pUser2->GetPassword() << std::endl; } } // 删除共享内存区 g_UserSMUPool.Finalize(); return 0;}
git:http://git.oschina.net/eclipser/sharememory.git
0 0
- C++简单封装共享内存
- 简单windows共享内存封装类
- 封装共享内存类
- C++共享内存封装类
- 共享内存简单入门
- C语言 共享内存
- C linux 共享内存
- c内存共享
- 2010/7/26 共享内存封装
- 封装ipc,共享内存,消息队列,信号量
- c#读写共享内存操作函数封装
- 一个共享内存封装类的源码
- 进程间共享内存操作简易封装
- 共享内存的简单应用
- linux 共享内存 简单例子
- win32共享内存简单实例
- linux-c: ipc_共享内存
- linux C共享内存函数
- 八、双色球彩票,股票,快递,身份证查询
- nyoj 5Binary String Matching
- Fedora下使用yum命令安装MySQL
- 【翻译】Android Support Library Features(二)
- 神句tag数量
- C++简单封装共享内存
- 用twitcurl C++库访问Twitter REST API 1.1
- A Graph Generation Package
- iOS-Bug: +[CATransaction synchronize] called within transaction
- java main函数 中 参数 String args 使用
- jetty服务器的安装和部署、新增到开机启动服务
- as3 判断,某个类是否继承于某个类,某个类是否实现某个接口的方法
- 今天开始写博客
- 每个人心里一亩一亩田,每个人心中一个一个梦