Chinaunix首页 | 论坛 | 博客
  • 博客访问: 852782
  • 博文数量: 168
  • 博客积分: 5431
  • 博客等级: 大校
  • 技术积分: 1560
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-22 11:56
文章存档

2015年(2)

2014年(1)

2013年(12)

2012年(12)

2011年(15)

2010年(5)

2009年(16)

2008年(41)

2007年(64)

分类: C/C++

2008-07-28 18:30:27

基于share memory的通信库的c++的封装(一)

  标准OS提供了许多久经考验的进程通信方式,如meassage queue,signal,event,fifo,local socket,semphare,mutex,critical section,file mapping等。这么多的通信方式我们该如何选用呢?由于我的这个架构是用于嵌入式方面的,因此对效率的要求很高,在此选择file mapping的特殊实现share memory。下面先简单介绍一下以上通信方式的优缺点。


1)file mapping

  通过将物理磁盘文件映射到kernel spcace的一块memory,再根据用户需要将该kernel memory映射到user space进程空间,从而实现在进程内部自由访问磁盘文件的功能。以上可以看出,进行两次映射是比较低效的并没有直接读写文件那么高效,那么OS为什么要提供这种方式呢?自然是有理由的!只要不unmap,可以在进程的整个生命周期方便的通过一个指针对文件进行操作而且OS本身会优化访问物理磁盘,所以效率很高。


2)share memory

它是一种特殊的file mapping。当创建file mapping的时候不赋予该kernel memory任何物理设备,这样我们可以看出file mapping访问的低效部分便消除了,因此share memory的访问效率相对其他几种通信方式很有优势。但是share memory对于具体的问题必须进行自我管理造成了一点使用上的不变。一下就是我的封装:
    if (NULL == h_shmem){
        h_shmem = CreateFileMapping(INVALID_HANDLE_VALUE,
                            NULL, FILE_MAP_ALL_ACCESS, 0, sz, p);
    }

    if (h_shmem){
            p_shmem = (cESShareMemStruct*)MapViewOfFile(h_shmem,
                            FILE_MAP_ALL_ACCESS, 0, 0,
                            SIZE_OF_SHARE_MEMORY_MAPPED);

        if(p_shmem){
/*
 *    If the share memory in the kernel space is OK
 *    then call the share memory struct's constructor
 *    to make the share memory known by all proccesses!
 */
            p_shmem = new(p_shmem)cESShareMemStruct;
            //Init the share memory before using
            memset(p_shmem, 0x0, sizeof(cESShareMemStruct));
            return TRUE;
        }
        else
            return FALSE;
    }
    return FALSE;
enum {
    DATA_SEND_OUT = 0,
    DATA_RECEIVE = 1,
    DATA_BROADCAST,
};




#define SIZE_OF_SHARE_MEMORY_STRUCT        (sizeof(cESShareMemStruct))
#define UNKNOWN_SHARE_MEMORY            "Unknown share memory"
#define SIZE_OF_SHARE_MEMORY_MAPPED        SIZE_OF_SHARE_MEMORY_STRUCT

class cESIPCObject:public cESThread{
public:
    cESIPCObject():p_shmem(NULL),h_shmem(NULL),procsyc_lock(0){}
    
    cESIPCObject(BT8* p):p_shmem(NULL),h_shmem(NULL),procsyc_lock(p){}
   
    virtual ~cESIPCObject();

    BOOL inline init(BT8* = UNKNOWN_SHARE_MEMORY,
                    DWD32 sz = SIZE_OF_SHARE_MEMORY_STRUCT);
    VOID destroy(VOID);
        virtual VOID start(VOID) = 0;
    VOID stop();
//    BOOL send(VOID*) = 0;
//    BOOL receive(VOID*) = 0;
    virtual VOID thread_function() = 0;

/*
 *    Get the data written by other process
 */
    inline VOID* get_data(VOID*){};

/*
 *    Parse the data passed to me into a int type ID
 *    corresponding to a event type
 */
    virtual DWD32 parse_data(VOID*){ return -1; }

/*
 *    For judging the kind data, I mean send out or received
 */

        cESProcSycObject procsyc_lock;

protected:
    HANDLE h_shmem;
    cESShareMemStruct* p_shmem;

private:

};
阅读(1572) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~