WWW.LOUGH.COM.CN

加入收藏 | 设为首页 | 联系站长
首页 | Java | C&C++ | 数据库 | 经验交流
论坛首页 | 综合区 | 贴图区 | 狐朋狗友 | 学习区 | 站务区
博客首页 | IT技术 | WebServices | Hibernate | Java设计模式 | Struts | AJAX | 数据库
首页 | 中华古籍 | 网络原创 | 随记

共享内存使用

共享内存使用

这是一个同学写的关于共享内存的东西,封装了一些常用的数据结构,
在Redhat 9下编译通过,并且已经有了商业化的应用,目前还是比较稳
定的。下面是源代码:
lcli.cpp
#include "shmobjlink.h"
#include <unistd.h>
#include "mylog.h"
#include "obj.h"
int main()
{
    shmobjlink<testObj> charPoolIns(100,2000);
    int i;
    for(i=1;i<2001;i++)
    {
        testObj j;
        int ret;
        j.index = i;
        ret = charPoolIns.put(&j);
        sleep(1);
        if(ret == false)
        {
            mylog("no obj available");
            sleep(1);
        }
        mylog("ret = %d",j.index);
    }
    return 0;
}

lser.cpp

#include "shmobjlink.h"
#include <unistd.h>
#include "mylog.h"
#include <signal.h>
#include "obj.h"


shmobjlink<testObj> charPoolIns(100,2000);
void catchSignal(int sig)
{
    mylog("catch signal %d",sig);
    testObj i;
    testObj j;
    i.index = 2;
    while(charPoolIns.get(&j,&i)==true)    
    {
        mylog("get obj= %d",j.index);
    }
    mylog("ok");

    return;
}
int main()
{
    signal(SIGUSR1, catchSignal);

    while(1)
    {
        sleep(1);
    }
}


mylog.cpp
/*
 * this file provide log functionality
 * composed by antony 
 * 2003-1-1
 * copyright reserved
 */
/*
 *if PERFORMANCE is define check performance of program
 *this file provide performanc check global var
 */
#ifndef __MYLOG__H_
#define __MYLOG__H_ 
    #include "mylog.h"
    #ifdef PERFORMANCE
        struct timeval timeTTStart;  //记录时间
        struct timeval timeTTNow;
    #endif
#endif


mylog.h
/*
 * this file provide log functionality
 * composed by antony 
 * 2003-1-1
 * copyright reserved
 */
/*
 *if PERFORMANCE is define check performance of program
 *define MACRO for log
 */

#ifndef __MYLOG__H_
#define __MYLOG__H_

#define LOG_MAX_LEN 512
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <iostream>
#include <fstream>
using namespace std;

#ifdef PERFORMANCE
    extern struct timeval timeTTStart;  //记录时间
    extern struct timeval timeTTNow;
    inline int my_check_start()
    {
        return gettimeofday(&timeTTStart, NULL);
    }
    int my_check_start();
    #define my_check_point(fmt,arg...) { \
        char mylogTmpString[LOG_MAX_LEN], tmpTime[20]; \
        gettimeofday(&timeTTNow,NULL); \
        sprintf(mylogTmpString,fmt,##arg); \
        sprintf(tmpTime,"sec[%02d]m_sec[%06d]", \
        (timeTTNow.tv_usec - timeTTStart.tv_usec)>0? \
        (timeTTNow.tv_sec - timeTTStart.tv_sec):(timeTTNow.tv_sec - timeTTStart.tv_sec-1), \
        (timeTTNow.tv_usec - timeTTStart.tv_usec)>0?\
            (timeTTNow.tv_usec - timeTTStart.tv_usec):(1000000+(timeTTNow.tv_usec - timeTTStart.tv_usec)) ); \
        cout<<tmpTime<<"F["<<__FILE__<<"]["<<__FUNCTION__<<"]L["<<__LINE__<<"]" \
        <<":["<<mylogTmpString<<"]"<<endl; \
    }
    #define mylog(fmt,arg...) 
    #define get_now_time(fmt,arg...)
#else
    #define my_check_start()
    #define my_check_point(fmt,arg...) 
    #define mylog(fmt,arg...) {    \
        char mylogTmpString[LOG_MAX_LEN], tmpTime[20];\
        get_now_time(tmpTime ,sizeof(tmpTime)); \
        sprintf(mylogTmpString,fmt,##arg);\
        cout<<tmpTime<<"F["<<__FILE__<<"]["<<__FUNCTION__<<"]L["<<__LINE__<<"]"\
        <<":["<<mylogTmpString<<"]"<<endl;\
    }
    inline int get_now_time( char *str, int len)
    {
        struct tm * lt;
        time_t tick;
        char str_time[20];
        tick=time(NULL);
        lt=localtime(&tick);
        int len_time;

        sprintf(str_time,"[%02d:%02d:%02d:%02d]",lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_sec);
        if(len <(len_time=strlen(str_time)))
        {
            str[0] = 0;
            return 0;
        }
        else
        {
            strcpy(str,str_time);
            return len_time;
        }
    }
#endif

#endif

obj.cpp
#include "obj.h"

testObj::testObj()
{
}
testObj::~testObj()
{
}

bool testObj::operator==(testObj &another)
{
    return (this->index == another.index);
}
testObj& testObj::operator=(testObj &another)
{
    this->index = another.index;
    return *this;
}


obj.h
#ifndef _OBJ_H_
#define _OBJ_H_
#include <stdlib.h>
#include <errno.h>


class testObj
{
    public:
        int index;

        testObj();
        ~testObj();
        void setIndex(int in)
    {
        index = in;
    }
        bool operator==( testObj &another);
        testObj &operator=(testObj &another);
};
#endif


qcli.cpp
#include "shmobjqueue.h"
#include <unistd.h>
#include "mylog.h"
int main()
{
    int i;
    for(i=0;i<4000;i++)
    {
        shmobjqueue<int> charPoolIns(100,2000);
        i = charPoolIns.getSize();
        mylog("pool size %d",i);
        int j;
        int ret;
        j = i;
        ret = charPoolIns.put(&j);
        /*
        sleep(1);
        if(ret == false)
        {
            mylog("no space available");
            sleep(1);
        }
        mylog("ret = %d",j);
        */
        ret = charPoolIns.get(&j);
    }
    return 0;
}


qser.cpp
#include "shmobjqueue.h"
#include <unistd.h>
#include "mylog.h"
#include <signal.h>


shmobjqueue<int> charPoolIns(100,2000);
void catchSignal(int sig)
{
    mylog("catch signal %d",sig);
    int j;
    while(charPoolIns.get(&j)==true)    
    {
        mylog("get obj= %d",j);
    }
    mylog("ok");

    return;
}
int main()
{
    signal(SIGUSR1, catchSignal);

    while(1)
    {
        sleep(1);
    }
}


rmipcs.cpp
//antony for rm ipcs utlity
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include "../include/mylog.h"

int main(int argc, char **argv)
{
    int shmid;
    int semid;
    key_t shmkey;
    key_t semkey;

    if(argc != 4)
    {
        mylog("useage: rmipcs shmfile semfile project_id");
        exit(0);
    }

    char *pShmfile = argv[1];
    char *pSemfile = argv[2];

    int proj_id = atoi(argv[3]);

    shmkey = ftok(pShmfile, proj_id);
    shmid =  shmget(shmkey, 0, 0640);

    printf("shmid=%d\n", shmid);

    semkey = ftok(pSemfile, proj_id);
    semid =  semget(semkey, 0, 0640);
    printf("semid=%d\n",semid);

}

shmobjlink.cpp
/*
 * this file provide obj pool realization
 * composed by antony 
 * 2003-3-17
 * copyright reserved
 */
 /*
  *last modified 2003-3-25
  *still need to add code to realize search function
  */

#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include "shmobjlink.h"
#include "mylog.h"

template <class st > shmobjlink<st>::shmobjlink(int ipckey,unsigned int count)
{
    m_pShm = this->shmcreate(ipckey, count);
    if(m_pShm == NULL)
    {
        mylog("shm init error");
        assert(0);
    }
    
    this->m_pShmHead = (shmHead *)this->m_pShm;
    if(m_pShmHead->maxPoolSize != count)
    {
        mylog("max num %d,req count %d",m_pShmHead->maxPoolSize, count);
        assert(0);
    }
    this->asynInit(ipckey);
}

template <class st > shmobjlink<st>::~shmobjlink()
{
    this->detach();
}

template <class st > char* shmobjlink<st>::shmcreate(int ipckey, unsigned int count)
{
    int shmid = 0;
    char *l_pShm = NULL;
    key_t shmkey;

    unsigned int size = sizeof(shmHead)+count*sizeof(container);
    shmkey = ipckey;
    mylog("shmkey:%d",shmkey);
    shmid = shmget( shmkey, size, 0660 );
    if( shmid < 0 ) {
        shmid = shmget( shmkey, size, IPC_CREAT | 0660);
        if( shmid < 0 )
            return NULL;
        l_pShm = (char *) shmat( shmid, NULL, 0 );
        if( l_pShm == (void *)-1 )
               return NULL;
        ((shmHead *)l_pShm)->maxPoolSize = count;
        /* m_pShm 未赋值 */
        m_pShm = l_pShm;
        this->clearup();
    } else {
        mylog("attaching shm");
        l_pShm = (char *) shmat( shmid, NULL, 0 );
        if( l_pShm == (char *)-1 )
            return NULL;
    }
    return l_pShm;
}

template <class st > bool shmobjlink<st>::get(st *p_st)
{
    bool ret = false;
    container *l_pCurContainer;
    this->asynStart();
    l_pCurContainer = m_pShmHead->first;
    if( m_pShmHead->actPoolSize> 0)
    {
        ret  = true;
        memcpy(p_st, &l_pCurContainer->obj,sizeof(st));
        l_pCurContainer->status = false;
        m_pShmHead->first = l_pCurContainer->next;
        m_pShmHead->last->next = m_pShmHead->first;
        m_pShmHead->actPoolSize--;
    }
    else
    {
        mylog("error,pool size %d", m_pShmHead->actPoolSize);
    }
    this->asynEnd();
    return ret;
}

template <class st > bool shmobjlink<st>::get(st *p_st, st *p_stIndext)
{
    unsigned int loop;
    bool ret = false;
    container *l_pFirstContainer;

    this->asynStart();    
    l_pFirstContainer = m_pShmHead->first;
    for(loop=0;loop<m_pShmHead->actPoolSize;loop++)
    {
        if((m_pShmHead->first->obj) == *p_stIndext)
        {
            ret = true;
            memcpy(p_st, &(m_pShmHead->first->obj),sizeof(st));
            m_pShmHead->first->status = false;
            m_pShmHead->first = m_pShmHead->first->next;
            m_pShmHead->last->next = m_pShmHead->first;
            m_pShmHead->actPoolSize--;
            break;
        }
        this->moveNext();
    }
    this->asynEnd();
    return ret;
}

template <class st > bool shmobjlink<st>::search(st *p_stIndext)
{
    unsigned int loop;
    bool ret = false;
    container *l_pFirstContainer;

    this->asynStart();    
    l_pFirstContainer = m_pShmHead->first;
    for(loop=0;loop<m_pShmHead->actPoolSize;loop++)
    {
        if((m_pShmHead->first->obj) == *p_stIndext)
        {
            ret = true;
            break;
        }
        this->moveNext();
    }
    this->asynEnd();
    return ret;
}



template <class st > bool shmobjlink<st>::put(st *p_st)
{
    bool ret = false;
    container *l_pCrusingContainer = m_pShmHead->first;

    this->asynStart();
    if(m_pShmHead->actPoolSize< m_pShmHead->maxPoolSize)
    {
        while(l_pCrusingContainer != m_pShmHead->shmEnd )
        {
            if(l_pCrusingContainer->status == false)
                break;
            l_pCrusingContainer = l_pCrusingContainer ++;
        }
        if(l_pCrusingContainer != m_pShmHead->shmEnd)
        {
            ret = true;
            l_pCrusingContainer->status = true;

            memcpy(&(l_pCrusingContainer->obj), p_st, sizeof(st));
            l_pCrusingContainer->next = m_pShmHead->first;
            m_pShmHead->first = l_pCrusingContainer;
            m_pShmHead->last->next = m_pShmHead->first;
            m_pShmHead->actPoolSize ++;
            mylog("after put,size %d", m_pShmHead->actPoolSize);
        }
        else
        {
            mylog("reach no space found");
        }
    }
    else
    {
        mylog("pool is full");
    }
    this->asynEnd();
    return  ret;
}

template <class st > void shmobjlink<st>::clearup()
{
    shmHead *l_pShmHead = (shmHead *)this->m_pShm;
    container *l_pCrusingContainer = (container *)(this->m_pShm+sizeof(shmHead));

    this->asynStart();
    l_pShmHead->actPoolSize = 0;
    l_pShmHead->shmStart = (container *)(this->m_pShm+sizeof(shmHead));
    l_pShmHead->first = l_pShmHead->shmStart;
    l_pShmHead->last = l_pShmHead->shmStart;
    l_pShmHead->shmEnd = l_pShmHead->shmStart+l_pShmHead->maxPoolSize;

    while(l_pCrusingContainer != l_pShmHead->shmEnd)
    {
        l_pCrusingContainer->status = false;
        l_pCrusingContainer->next = NULL;
        l_pCrusingContainer = l_pCrusingContainer++;
    }
    this->asynEnd();
}

template <class st > bool shmobjlink<st>::moveNext()
{
    bool ret = false;
    shmHead *l_pShmHead = (shmHead *)m_pShm;

    //this->asynStart();
    if(l_pShmHead->first->next != NULL)
    {
        ret = true;
        l_pShmHead->last = l_pShmHead->first;
        l_pShmHead->first = l_pShmHead->last->next;
    }
    //this->asynEnd();
    return ret;
}

template <class st > void shmobjlink<st>::delCur()
{
    
}

template <class st > void shmobjlink<st>::asynInit(int ipckey)
{
    key_t semkey;
    int value;
    semkey = ipckey;
    mylog("semkey=%d",semkey);

    m_iSemid = semget(semkey, 0, 0640);
    if(m_iSemid <0)
    {

        m_iSemid = semget(semkey, 1, IPC_CREAT|0640);
        if(m_iSemid<0)
        {
            mylog("error:%s",strerror( errno ));
        }
        arg.val = 1;
        value = semctl(m_iSemid,0, SETVAL, arg);
        value = semctl(m_iSemid,0, GETVAL, arg);
        mylog("create sem value=%d",value); 
        return;
    }
    else
    {
        value = semctl(m_iSemid,0, GETVAL, arg);
        mylog("sem exist,value=%d",value);
        return;
    }
}

template <class st > void shmobjlink<st>::asynStart()
{
    struct sembuf sops;
    int value;

    sops.sem_num=0;
    sops.sem_op=-1;
    sops.sem_flg=0;

    value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
    mylog("before AsyStart %d", value);
    value = semop(m_iSemid,&sops,1);
    mylog("after AsyStart %d", value);
    return;
}

template <class st > void shmobjlink<st>::asynEnd()
{
    struct sembuf sops;
    int value;

    sops.sem_num=0;
    sops.sem_op=1;
    sops.sem_flg=0;

    value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
    mylog("before AsyEnd %d", value);
    value = semop(m_iSemid,&sops,1);
    value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
    mylog("after AsyEnd %d", value);
    return;
}
template <class st > void shmobjlink<st>::detach()
{
    if(m_pShm > (void *)0)
        shmdt(m_pShm);
}
template <class st > bool shmobjlink<st>::isEmpty()
{
    if(m_pShmHead->actPoolSize == 0)
        return true;
    else
        return false;
}



shmobjlink.h
/*
 * this file provide obj pool realization
 * composed by antony 
 * 2003-3-24
 * copyright reserved
 */
/*
 * last modified 2003-3-25
 */
#ifndef __SHMBOJLINK_H_
#define __SHMBOJLINK_H_
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include "obj.h"

template <class st> class shmobjlink
{

    private:

    union semun {
            int val;
            struct semid_ds *buf;
            ushort *array;
      } arg;

    typedef struct container
    {
        bool status;
        st obj;
        container *next;
    };

    typedef struct 
    {
        unsigned int maxPoolSize; 
        unsigned int actPoolSize;
        container *shmStart;
        container *shmEnd;

        container *last;
        container *first;
    }shmHead;

        char *m_pShm;
        shmHead *m_pShmHead;
        int m_iSemid;

        char *shmcreate(int ipckey, unsigned int count);
        void asynInit(int ipckey);
        void asynStart();
        void asynEnd();
        /* move to next node */
        bool moveNext();
        void delCur();
    public:
        //create memory to contain num st obj
        shmobjlink(int ipckey, unsigned int count );
        ~shmobjlink();
        //get first obj from pool
        bool get(st *) ;
        //search obj from pool
        bool search(st *) ;
        //get a obj by index
        bool get(st *out, st *in);
        //put a obj to pool
        bool put(st *);
        //clear up all objs in pool
        void clearup();
        //detach from shm
        void detach();
        //return true if empty
        bool isEmpty();
};
/*
 * just realize the following class
 */
template class shmobjlink<char>;
template class shmobjlink<int>;
template class shmobjlink<testObj>;
#endif

shmobjlinkeq.cpp
/*
 * this file provide obj pool realization
 * composed by antony 
 * 2003-3-17
 * copyright reserved
 */
 /*
  *last modified 2003-3-25
  *still need to add code to realize search function
  */

#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include "shmobjlinkeq.h"
#include "mylog.h"

template <class st, class eq> shmobjlinkeq<st, eq>::shmobjlinkeq(int ipckey,unsigned int count)
{
    m_pShm = this->shmcreate(ipckey, count);
    if(m_pShm == NULL)
    {
        mylog("shm init error");
        assert(0);
    }
    
    this->m_pShmHead = (shmHead *)this->m_pShm;
    if(m_pShmHead->maxPoolSize != count)
    {
        mylog("max num %d,req count %d",m_pShmHead->maxPoolSize, count);
        assert(0);
    }
    this->asynInit(ipckey);
}

template <class st, class eq> shmobjlinkeq<st, eq>::~shmobjlinkeq()
{
    this->detach();
}

template <class st, class eq> char* shmobjlinkeq<st, eq>::shmcreate(int ipckey, unsigned int count)
{
    int shmid = 0;
    char *l_pShm = NULL;
    key_t shmkey;

    unsigned int size = sizeof(shmHead)+count*sizeof(container);
    shmkey = ipckey;
    mylog("shmkey:%d",shmkey);
    shmid = shmget( shmkey, size, 0660 );
    if( shmid < 0 ) {
        shmid = shmget( shmkey, size, IPC_CREAT | 0660);
        if( shmid < 0 )
            return NULL;
        l_pShm = (char *) shmat( shmid, NULL, 0 );
        if( l_pShm == (void *)-1 )
               return NULL;
        ((shmHead *)l_pShm)->maxPoolSize = count;
        /* m_pShm 未赋值 */
        m_pShm = l_pShm;
        this->clearup();
    } else {
        mylog("attaching shm");
        l_pShm = (char *) shmat( shmid, NULL, 0 );
        if( l_pShm == (char *)-1 )
            return NULL;
    }
    return l_pShm;
}

template <class st, class eq> bool shmobjlinkeq<st, eq>::get(st *p_st)
{
    bool ret = false;
    container *l_pCurContainer;
    this->asynStart();
    l_pCurContainer = m_pShmHead->first;
    if( m_pShmHead->actPoolSize> 0)
    {
        ret  = true;
        memcpy(p_st, &l_pCurContainer->obj,sizeof(st));
        l_pCurContainer->status = false;
        m_pShmHead->first = l_pCurContainer->next;
        m_pShmHead->last->next = m_pShmHead->first;
        m_pShmHead->actPoolSize--;
    }
    else
    {
        mylog("error,pool size %d", m_pShmHead->actPoolSize);
    }
    this->asynEnd();
    return ret;
}

template <class st, class eq> bool shmobjlinkeq<st, eq>::get(st *p_st, st *p_stIndext)
{
    unsigned int loop;
    bool ret = false;
    container *l_pFirstContainer;

    this->asynStart();    
    l_pFirstContainer = m_pShmHead->first;
    for(loop=0;loop<m_pShmHead->actPoolSize;loop++)
    {
        if((m_pShmHead->first->obj) == *p_stIndext)
        {
            ret = true;
            memcpy(p_st, &(m_pShmHead->first->obj),sizeof(st));
            m_pShmHead->first->status = false;
            m_pShmHead->first = m_pShmHead->first->next;
            m_pShmHead->last->next = m_pShmHead->first;
            m_pShmHead->actPoolSize--;
            break;
        }
        this->moveNext();
    }
    this->asynEnd();
    return ret;
}

template <class st, class eq> bool shmobjlinkeq<st, eq>::search(st *p_stIndext)
{
    unsigned int loop;
    bool ret = false;
    container *l_pFirstContainer;

    this->asynStart();    
    l_pFirstContainer = m_pShmHead->first;
    for(loop=0;loop<m_pShmHead->actPoolSize;loop++)
    {
        if((m_pShmHead->first->obj) == *p_stIndext)
        {
            ret = true;
            break;
        }
        this->moveNext();
    }
    this->asynEnd();
    return ret;
}



template <class st, class eq> bool shmobjlinkeq<st, eq>::put(st *p_st)
{
    bool ret = false;
    container *l_pCrusingContainer = m_pShmHead->first;

    this->asynStart();
    if(m_pShmHead->actPoolSize< m_pShmHead->maxPoolSize)
    {
        while(l_pCrusingContainer != m_pShmHead->shmEnd )
        {
            if(l_pCrusingContainer->status == false)
                break;
            l_pCrusingContainer = l_pCrusingContainer ++;
        }
        if(l_pCrusingContainer != m_pShmHead->shmEnd)
        {
            ret = true;
            l_pCrusingContainer->status = true;

            memcpy(&(l_pCrusingContainer->obj), p_st, sizeof(st));
            l_pCrusingContainer->next = m_pShmHead->first;
            m_pShmHead->first = l_pCrusingContainer;
            m_pShmHead->last->next = m_pShmHead->first;
            m_pShmHead->actPoolSize ++;
            mylog("after put,size %d", m_pShmHead->actPoolSize);
        }
        else
        {
            mylog("reach no space found");
        }
    }
    else
    {
        mylog("pool is full");
    }
    this->asynEnd();
    return  ret;
}

template <class st, class eq> void shmobjlinkeq<st, eq>::clearup()
{
    shmHead *l_pShmHead = (shmHead *)this->m_pShm;
    container *l_pCrusingContainer = (container *)(this->m_pShm+sizeof(shmHead));

    this->asynStart();
    l_pShmHead->actPoolSize = 0;
    l_pShmHead->shmStart = (container *)(this->m_pShm+sizeof(shmHead));
    l_pShmHead->first = l_pShmHead->shmStart;
    l_pShmHead->last = l_pShmHead->shmStart;
    l_pShmHead->shmEnd = l_pShmHead->shmStart+l_pShmHead->maxPoolSize;

    while(l_pCrusingContainer != l_pShmHead->shmEnd)
    {
        l_pCrusingContainer->status = false;
        l_pCrusingContainer->next = NULL;
        l_pCrusingContainer = l_pCrusingContainer++;
    }
    this->asynEnd();
}

template <class st, class eq> bool shmobjlinkeq<st, eq>::moveNext()
{
    bool ret = false;
    shmHead *l_pShmHead = (shmHead *)m_pShm;

    //this->asynStart();
    if(l_pShmHead->first->next != NULL)
    {
        ret = true;
        l_pShmHead->last = l_pShmHead->first;
        l_pShmHead->first = l_pShmHead->last->next;
    }
    //this->asynEnd();
    return ret;
}

template <class st, class eq> void shmobjlinkeq<st, eq>::delCur()
{
    
}

template <class st, class eq> void shmobjlinkeq<st, eq>::asynInit(int ipckey)
{
    key_t semkey;
    int value;
    semkey = ipckey;
    mylog("semkey=%d",semkey);

    m_iSemid = semget(semkey, 0, 0640);
    if(m_iSemid <0)
    {

        m_iSemid = semget(semkey, 1, IPC_CREAT|0640);
        if(m_iSemid<0)
        {
            mylog("error:%s",strerror( errno ));
        }
        arg.val = 1;
        value = semctl(m_iSemid,0, SETVAL, arg);
        value = semctl(m_iSemid,0, GETVAL, arg);
        mylog("create sem value=%d",value); 
        return;
    }
    else
    {
        value = semctl(m_iSemid,0, GETVAL, arg);
        mylog("sem exist,value=%d",value);
        return;
    }
}

template <class st, class eq> void shmobjlinkeq<st, eq>::asynStart()
{
    struct sembuf sops;
    int value;

    sops.sem_num=0;
    sops.sem_op=-1;
    sops.sem_flg=0;

    value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
    mylog("before AsyStart %d", value);
    value = semop(m_iSemid,&sops,1);
    mylog("after AsyStart %d", value);
    return;
}

template <class st, class eq> void shmobjlinkeq<st, eq>::asynEnd()
{
    struct sembuf sops;
    int value;

    sops.sem_num=0;
    sops.sem_op=1;
    sops.sem_flg=0;

    value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
    mylog("before AsyEnd %d", value);
    value = semop(m_iSemid,&sops,1);
    value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
    mylog("after AsyEnd %d", value);
    return;
}
template <class st, class eq> void shmobjlinkeq<st, eq>::detach()
{
    if(m_pShm > (void *)0)
        shmdt(m_pShm);
}
template <class st, class eq> bool shmobjlinkeq<st, eq>::isEmpty()
{
    if(m_pShmHead->actPoolSize == 0)
        return true;
    else
        return false;
}



shmobjlinkeq.h
/*
 * this file provide obj pool realization
 * composed by antony 
 * 2003-3-24
 * copyright reserved
 */
/*
 * last modified 2003-3-25
 */
#ifndef __SHMBOJLINK_H_
#define __SHMBOJLINK_H_
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include "obj.h"
struct eqint
{
  bool operator()(const int c1, const int c2) const
  {
    return c1 == c2;
  }
};


template <class st, class eq> class shmobjlinkeq
{

    private:

    union semun {
            int val;
            struct semid_ds *buf;
            ushort *array;
      } arg;

    typedef struct container
    {
        bool status;
        st obj;
        container *next;
    };

    typedef struct 
    {
        unsigned int maxPoolSize; 
        unsigned int actPoolSize;
        container *shmStart;
        container *shmEnd;

        container *last;
        container *first;
    }shmHead;

        char *m_pShm;
        shmHead *m_pShmHead;
        int m_iSemid;

        char *shmcreate(int ipckey, unsigned int count);
        void asynInit(int ipckey);
        void asynStart();
        void asynEnd();
        /* move to next node */
        bool moveNext();
        void delCur();
    public:
        //create memory to contain num st obj
        shmobjlinkeq(int ipckey, unsigned int count);
        ~shmobjlinkeq();
        //get first obj from pool
        bool get(st *) ;
        //search obj from pool
        bool search(st *) ;
        //get a obj by index
        bool get(st *out, st *in);
        //put a obj to pool
        bool put(st *);
        //clear up all objs in pool
        void clearup();
        //detach from shm
        void detach();
        //return true if empty
        bool isEmpty();
};
/*
 * just realize the following class
 */
template class shmobjlinkeq<int,eqint>;
//template class shmobjlinkeq<int>;
//template class shmobjlinkeq<testObj>;
#endif

shmobjqueue.cpp
/*
 * this file provide obj queue in share memory realization
 * composed by antony 
 * 2003-3-17
 * copyright reserved
 */
 /*
  *m_ppObjLast modified 2003-3-18
  *still need to add code to maintain shm consistent 
  */
//modified by antony 2003-03-23
//change shm create mode 

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include "shmobjqueue.h"
#include "mylog.h"

template <class st > shmobjqueue<st>::shmobjqueue(int ipckey,int num)
{
    m_ipckey = ipckey;
    mylog("init queue shmobjqueue key=%x", ipckey);
    this->m_iObjSize = sizeof(st);
    //m_pShm = this->shmcreate(shmfilename, proj_id, num*this->m_iObjSize +sizeof(int)*4);
    m_pShm = this->shmcreate(ipckey, num);
    if(m_pShm == NULL)
    {
        assert(0);
    }
    this->m_piMaxPoolSize = (int *)m_pShm;
    if(*this->m_piMaxPoolSize != num)
    {
        mylog("pool size actual size:%d,reques size:%d",*this->m_piMaxPoolSize,num);
        assert(0);
    }
    this->m_piPoolSize = (int *)((char *)this->m_piMaxPoolSize+sizeof(this->m_piMaxPoolSize));
    this->m_ppObjFirst = (st **)((char *)this->m_piPoolSize+sizeof(this->m_piPoolSize));
    this->m_ppObjLast = (st **)((char *)this->m_ppObjFirst+sizeof(this->m_ppObjFirst));

    this->m_pMemStart = (st *)((char *)this->m_ppObjLast+ sizeof(this->m_ppObjLast));
    this->m_pMemEnd = (st *)(this->m_pMemStart + *(this->m_piMaxPoolSize));

    this->asynInit(ipckey);
}

template <class st > shmobjqueue<st>::~shmobjqueue()
{
    mylog("destruct[%x]",m_ipckey);
    this->detach();
}

template <class st > char* shmobjqueue<st>::shmcreate(int ipckey, unsigned long num)
{
    int shmid = 0;
    int size;
    key_t shmkey;
    
    if(num != 0)
        size = num*this->m_iObjSize +sizeof(int)*4;
    else
        size = 0;
    shmkey = ipckey;

       shmid = shmget( shmkey, size, 0640 );
        if( shmid < 0 ) {
        shmid = shmget( shmkey, size, IPC_CREAT | 0640);
        if( shmid < 0 )
            return NULL;
        m_pShm = (char *) shmat( shmid, NULL, 0 );
        if( m_pShm == (char *)-1 )
               return NULL;
        memset( m_pShm, 0, size );
        *(int *)m_pShm = num;
        *(int *)((int)m_pShm+sizeof(int)) = 0;
        *(void **)((int)m_pShm+sizeof(int)*2) = (void *)((int)m_pShm + sizeof(int)*4);
        *(void **)((int)m_pShm+sizeof(int)*3) = (void *)((int)m_pShm + sizeof(int)*4);

    } else {
        mylog("attaching shm");
        m_pShm = (char *) shmat( shmid, NULL, 0 );
        if( m_pShm == (void *)-1 )
    {
        mylog("error:%s",strerror(errno));
            return NULL;
    }
    }
    return m_pShm;
}

template <class st > bool shmobjqueue<st>::get(st *p_st)
{
    bool ret;
    this->asynStart();
    mylog("before get,pool size=%d",*this->m_piPoolSize);
    if( *this->m_piPoolSize <0)
    {
        ret =  false; 
        mylog("m_piPoolSize error:%d", *this->m_piPoolSize);
        //force to clearup;
        this->clearup();
    }
    else if(*this->m_piPoolSize == 0)
    {
        ret = false;
        mylog("pool is empty");
        if(*this->m_ppObjFirst != *this->m_ppObjLast )
        {
            mylog("consistent error");
        }
    }
    else
    {
        ret = true;
        (*this->m_piPoolSize)--;
        memcpy(p_st, *this->m_ppObjFirst, sizeof(st));
        *this->m_ppObjFirst = (st *)((char *)*this->m_ppObjFirst+this->m_iObjSize );
        //reach m_pMemEnd,loop to m_pMemStart point
        if(*this->m_ppObjFirst == this->m_pMemEnd)
            *this->m_ppObjFirst = this->m_pMemStart;
        if(*this->m_ppObjFirst == *this->m_ppObjLast)
        {
            *this->m_piPoolSize = 0;
        }
    }
    mylog("after get,pool size=%d",*this->m_piPoolSize);
    this->asynEnd();
    return ret;
}

template <class st > bool shmobjqueue<st>::put(st *p_st)
{
    bool ret;
    this->asynStart();
    mylog("before put,pool size=%d",*this->m_piPoolSize);
    if(*this->m_piPoolSize >*this->m_piMaxPoolSize)
    {

        mylog("pool size error,max size:%d,actual size:%d",
            *this->m_piMaxPoolSize,*this->m_piPoolSize);
        ret =  false; 
    }
    else if(*this->m_piPoolSize ==*this->m_piMaxPoolSize)
    {
        ret =  false; 
        mylog("pool is full,max size:%d",*this->m_piMaxPoolSize);
        if(*this->m_ppObjFirst != *this->m_ppObjLast )
        {
            mylog("consistent error");
        }
    }
    else
    {
        ret = true;
        memcpy(*this->m_ppObjLast,p_st, sizeof(st));
        *this->m_ppObjLast = (st *)((char *)*this->m_ppObjLast+this->m_iObjSize );
        if(*this->m_ppObjLast == this->m_pMemEnd)
            *this->m_ppObjLast = this->m_pMemStart;
        (*this->m_piPoolSize)++;
    }
    mylog("after put,pool size=%d",*this->m_piPoolSize);
    this->asynEnd();
    return  ret;
}

template <class st > void shmobjqueue<st>::clearup()
{
    this->asynStart();
    *this->m_ppObjFirst = this->m_pMemStart;
    *this->m_ppObjLast = this->m_pMemStart;
    *this->m_piPoolSize = 0;
    this->asynEnd();
}

template <class st > void shmobjqueue<st>::asynInit(int ipckey)
{
    key_t semkey;
    int value;
    semkey = ipckey;

    m_iSemid = semget(semkey, 0, 0640);
    if(m_iSemid <0)
    {

        m_iSemid = semget(semkey, 1, IPC_CREAT|0640);
        if(m_iSemid<0)
        {
            mylog("error:%s",strerror( errno ));
        }
        arg.val = 1;
        value = semctl(m_iSemid,0, SETVAL, arg);
        mylog("create sem value=%d",value); 
        return;
    }
    else
    {
        value = semctl(m_iSemid,0, GETVAL, arg);
        mylog("sem exist,value=%d",value);
        return;
    }
}

template <class st > void shmobjqueue<st>::asynStart()
{
    struct sembuf sops;
    int value;

    sops.sem_num=0;
    sops.sem_op=-1;
    sops.sem_flg=0;

//    value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
//    mylog("before AsyStart %d", value);
    value = semop(m_iSemid,&sops,1);
//    mylog("after AsyStart %d", value);
    return;
}

template <class st > void shmobjqueue<st>::asynEnd()
{
    struct sembuf sops;
    int value;

    sops.sem_num=0;
    sops.sem_op=1;
    sops.sem_flg=0;

//    value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
//    mylog("before AsyEnd %d", value);
    value = semop(m_iSemid,&sops,1);
//    value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
//    mylog("after AsyEnd %d", value);
    return;
}
template <class st > void shmobjqueue<st>::detach()
{
    if(m_pShm > (void *)0)
        shmdt(m_pShm);
    mylog("ipckey=%x", m_ipckey);
}

template <class st > bool shmobjqueue<st>::isEmpty()
{
    if(*(this->m_piPoolSize) == 0)
        return true;
    else
        return false;
}


template <class st > int shmobjqueue<st>::getSize()
{
    int l_size;
    asynStart();
    l_size = *m_piPoolSize;
    asynEnd();
    return l_size; 
}

template <class st > bool shmobjqueue<st>::isFull()
{
    bool l_bRet;
    asynStart();
    l_bRet = (*m_piPoolSize == *m_piMaxPoolSize);
    asynEnd();
    return l_bRet;
}


shmobjqueue.h
/*
 * this file provide obj queue in share memory realization
 * composed by antony 
 * 2003-3-17
 * copyright reserved
 */

#ifndef __SHMBOJQUEUE_H_
#define __SHMBOJQUEUE_H_
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include "../include/msg_struct.h"

template <class st> class shmobjqueue
{

    private:
        char *m_pShm;
        int m_iSemid;
        int m_iObjSize;
        int *m_piPoolSize;
        int *m_piMaxPoolSize;

        st *m_pMemStart;   //memory m_pMemStart
        st *m_pMemEnd;     //memorr m_pMemEnd;


        st **m_ppObjFirst;  //m_ppObjFirst  node;
        st **m_ppObjLast;   //m_ppObjLast  node;
    union semun {
            int val;
            struct semid_ds *buf;
            ushort *array;
      } arg;

        char *shmcreate(int ipckey, unsigned long size);
        void asynInit(int ipckey);
        void asynStart();
        void asynEnd();

    public:
        //create memory to contain num st obj
        shmobjqueue(int ipckey, int num = 5000 );
        ~shmobjqueue();
        //get a obj from pool
        bool get(st *);
        //put a obj to pool
        bool put(st *);
        //clear up all objs in pool
        void clearup();
        //detach from shm
        void detach();
        //return true if empty
        bool isEmpty();
        //return pool size
        int getSize();
        //return is full
        bool isFull();
        int m_ipckey;
};
/*
 * just realize the following class
 */
template class shmobjqueue<char>;
template class shmobjqueue<int>;
template class shmobjqueue<recv_node_stru>;
template class shmobjqueue<submit_node_stru>;
#endif


shmobjvector.cpp
/*
 * this file provide obj pool realization
 * composed by antony 
 * 2003-3-17
 * copyright reserved
 */
 /*
  *last modified 2003-3-25
  *still need to add code to realize search function
  */

#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include "shmobjvector.h"
#include "mylog.h"
#include "obj.h"

template <class st > shmobjvector<st>::shmobjvector(int ipckey,unsigned int count)
{
    m_pCurContainer = NULL;
    m_pShm = this->shmcreate(ipckey, count);
    if(m_pShm == NULL)
    {
        mylog("shm init error");
        assert(0);
    }
    
    this->m_pShmHead = (shmHead *)this->m_pShm;
    if(m_pShmHead->maxPoolSize != count)
    {
        mylog("max num %d,req count %d",m_pShmHead->maxPoolSize, count);
        assert(0);
    }
    //m_pCurContainer = m_pShmHead->shmStart;
    this->asynInit(ipckey);
}

template <class st > shmobjvector<st>::~shmobjvector()
{
    this->detach();
}

template <class st > bool shmobjvector<st>::setId(unsigned int id)
{
    bool ret = false;
    if(m_pShmHead->maxPoolSize >id)
    {
        ret = true;
        m_pCurContainer = m_pShmHead->shmStart+ id;
    }
    else
    {
        m_pCurContainer = NULL;
        mylog("id error");
    }
    return ret;
}

template <class st > char* shmobjvector<st>::shmcreate(int ipckey, unsigned int count)
{
    int shmid = 0;
    unsigned int i;
    char *l_pShm = NULL;
    container *l_pContainer = NULL;

    key_t shmkey;
    shmkey = ipckey;

    unsigned int size = sizeof(shmHead)+count*sizeof(container);

    mylog("shmkey:%d",shmkey);
    shmid = shmget( shmkey, size, 0660 );
    if( shmid < 0 ) {
        shmid = shmget( shmkey, size, IPC_CREAT | 0660);
        if( shmid < 0 )
            return NULL;
        l_pShm = (char *) shmat( shmid, NULL, 0 );
        if( l_pShm == (void *)-1 )
               return NULL;
        ((shmHead *)l_pShm)->maxPoolSize = count;
        ((shmHead *)l_pShm)->actPoolSize = 0;
        /* m_pShm 未赋值 */
        m_pShm = l_pShm;
        ((shmHead *)l_pShm)->shmStart =(container *)((char *)l_pShm+sizeof(shmHead)); 
        ((shmHead *)l_pShm)->shmEnd =((shmHead *)l_pShm)->shmStart+count; 
        l_pContainer = ((shmHead *)l_pShm)->shmStart;
        for(i=0;i<count;i++)
        {
            l_pContainer->status = false;
            l_pContainer++;
        }
    } else {
        mylog("attaching shm");
        l_pShm = (char *) shmat( shmid, NULL, 0 );
        if( l_pShm == (char *)-1 )
            return NULL;
    }
    return l_pShm;
}

template <class st > bool shmobjvector<st>::get(st *p_st)
{
    bool ret = false;
    if(m_pCurContainer != NULL)
    {
        if(m_pCurContainer->status == true)
        {
            ret = true;
            mylog("get valid status");
            this->asynStart();
            memcpy( p_st, &m_pCurContainer->obj, sizeof(st));
            this->asynEnd();
        }
        else
            mylog("get invalid status");
    }
    else
    {
        mylog("init error");
    }
    return ret;
}


template <class st > bool shmobjvector<st>::put(st *p_st)
{
    bool ret = false;    
    if(m_pCurContainer != NULL)
    {
        ret = true;
        this->asynStart();
        if(m_pCurContainer->status == true)
        {
            mylog("update status");
        }
        else
        {
            mylog("init status");
            m_pCurContainer->status = true;
        }
        memcpy(&m_pCurContainer->obj, p_st, sizeof(st));
        this->asynEnd();
    }
    else
    {
        mylog("init error");
    }
    return  ret;
}


template <class st > void shmobjvector<st>::asynInit(int ipckey)
{
    key_t semkey;
    int value;
    semkey = ipckey;
    mylog("semkey=%d",semkey);

    m_iSemid = semget(semkey, 0, 0640);
    if(m_iSemid <0)
    {

        m_iSemid = semget(semkey, 1, IPC_CREAT|0640);
        if(m_iSemid<0)
        {
            mylog("error:%s",strerror( errno ));
        }
        arg.val = 1;
        value = semctl(m_iSemid,0, SETVAL, arg);
        value = semctl(m_iSemid,0, GETVAL, arg);
        mylog("create sem value=%d",value); 
        return;
    }
    else
    {
        value = semctl(m_iSemid,0, GETVAL, arg);
        mylog("sem exist,value=%d",value);
        return;
    }
}

template <class st > void shmobjvector<st>::asynStart()
{
    struct sembuf sops;
    int value;

    sops.sem_num=0;
    sops.sem_op=-1;
    sops.sem_flg=0;

    value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
    mylog("before AsyStart %d", value);
    value = semop(m_iSemid,&sops,1);
    mylog("after AsyStart %d", value);
    return;
}

template <class st > void shmobjvector<st>::asynEnd()
{
    struct sembuf sops;
    int value;

    sops.sem_num=0;
    sops.sem_op=1;
    sops.sem_flg=0;

    value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
    mylog("before AsyEnd %d", value);
    value = semop(m_iSemid,&sops,1);
    value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
    mylog("after AsyEnd %d", value);
    return;
}
template <class st > void shmobjvector<st>::detach()
{
    if(m_pShm > (void *)0)
        shmdt(m_pShm);
}
template <class st > bool shmobjvector<st>::isEmpty()
{
    if(m_pShmHead->actPoolSize == 0)
        return true;
    else
        return false;
}

/*
 * just realize the following class
 */
template class shmobjvector<char>;
template class shmobjvector<int>;
template class shmobjvector<testObj>;


shmobjvector.h
/*
 * this file provide obj pool realization
 * composed by antony 
 * 2003-3-24
 * copyright reserved
 */
/*
 * last modified 2003-3-25
 */
#ifndef __SHMBOJVECTOR_H_
#define __SHMBOJVECTOR_H_
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

template <class st> class shmobjvector
{

    private:

    union semun {
            int val;
            struct semid_ds *buf;
            ushort *array;
      } arg;

    typedef struct container
    {
        bool status;
        st obj;
    };

    typedef struct 
    {
        unsigned int maxPoolSize; 
        unsigned int actPoolSize;
        container *shmStart;
        container *shmEnd;
    }shmHead;

        char *m_pShm;
        shmHead *m_pShmHead;
        container *m_pCurContainer;
        int m_iSemid;

        char *shmcreate(int ipckey, unsigned int count);
        void asynInit(int ipckey);
        void asynStart();
        void asynEnd();

    public:
        //create memory to contain num st obj
        shmobjvector(int ipckey, unsigned int count);
        ~shmobjvector();
        //get first obj from pool
        bool setId(unsigned int) ;
        //put a obj to pool
        bool update(st *);
        //put a obj to pool
        bool put(st *);
        bool get(st *);
        bool isEmpty();

        //detach from shm
        void detach();
};
#endif

vcli.cpp
#include "shmobjvector.h"
#include <unistd.h>
#include "mylog.h"
int main()
{
    shmobjvector<int> charPoolIns(100,2000);
    int i;
    for(i=0;i<2000;i++)
    {
        int j=0;
        charPoolIns.setId(1999);
        charPoolIns.put(&i);
        charPoolIns.get(&j);
        sleep(1);
        mylog("%d = %d",i,j);
    }
    return 0;
}


makefile
CFLAGS=-g -O2 -Wall
DLLFLAGS = -fPIC -DPIC
TARGET=qcli qser lcli lser vcli rmipcs libshmobjpool.a 
OBJS=shmobjvector.o shmobjqueue.o shmobjlink.o shmobjlinkeq.o obj.o 
ORACLE_HOME=/usr/local/oracle/app
CC=g++

all:$(TARGET)
    cp *.h ../include/
    cp *.a ../lib/

qcli:$(OBJS) qcli.o
    $(CC) $(LDFLAGS) -g -o $@ $^
qser:$(OBJS) qser.o
    $(CC) $(LDFLAGS) -g -o $@ $^
lcli:$(OBJS) lcli.o
    $(CC) $(LDFLAGS) -g -o $@ $^
lser:$(OBJS) lser.o
    $(CC) $(LDFLAGS) -g -o $@ $^
vcli:$(OBJS) vcli.o
    $(CC) $(LDFLAGS) -g -o $@ $^
leqcli:$(OBJS) leqcli.o
    $(CC) $(LDFLAGS) -g -o $@ $^
leqser:$(OBJS) leqser.o
    $(CC) $(LDFLAGS) -g -o $@ $^
rmipcs:rmipcs.o 
    $(CC) $(LDFLAGS) -g -o $@ $^
libshmobjpool.a:$(OBJS) 
    ar -rv $@ $^
    


.SUFFIXES:.o .h
.SUFFIXES:.cpp .o

.cpp.o:
    $(CC) -c $(CFLAGS) -o $@ $< -I $(ORACLE_HOME)/rdbms/demo -I$(ORACLE_HOME)/rdbms/public -I$(ORACLE_HOME)/network/public 

clean:
    rm -f *.o $(TARGET)

remake: clean $(TARGET)

关于我们 | 站点地图 | 免责声明 | 联系我们 | ©2003-2007 Lough.com.cn 京ICP备06060948号