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