linux 共享内存消息队列使用

来源:互联网 发布:4g网络必须用4g手机吗 编辑:程序博客网 时间:2024/05/21 18:19

共享内存和消息队列使用

/******************************************************************************                  版权所有 (C), 2001-2011,  ******************************************************************************  文 件 名   : drv_app_mem_master.c  版 本 号   : 初稿  作    者   : zhangjinlei  生成日期   : 2012年5月17日星期四  最近修改   :  功能描述   : 内存共享主机端主文件  函数列表   :              main  修改历史   :  1.日    期   : 2012年5月17日星期四    作    者   : zhangjinlei    修改内容   : 创建文件******************************************************************************//*----------------------------------------------* * 包含头文件                                   * *----------------------------------------------*/#include <stdio.h> #include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/ipc.h> #include <sys/shm.h>#include <sys/sem.h>#include "drv_app_common.h"/*----------------------------------------------* * 外部变量说明                                 * *----------------------------------------------*//*----------------------------------------------* * 外部函数原型说明                             * *----------------------------------------------*//*----------------------------------------------* * 内部函数原型说明                             * *----------------------------------------------*//*----------------------------------------------* * 全局变量                                     * *----------------------------------------------*//*----------------------------------------------* * 模块级变量                                   * *----------------------------------------------*/static int g_iReadSemID;static int g_iWriteSemID;/*----------------------------------------------* * 常量定义                                     * *----------------------------------------------*//*----------------------------------------------* * 宏定义                                       * *----------------------------------------------*/#define   DRV_APP_MSG_QUE_FILE_NAME "."                  /* 消息队列指定文件名 */#define   DRV_APP_SHARE_MEMORY_SIZE 81920                /* 共享内存的大小 *//* BEGIN: Added by zhangjinlei, 2012/5/18 */union semun { int iValue; struct semid_ds *pstBuffer; unsigned short *pusArray;}arg;/***************************************************************************** 函 数 名  : DRV_APP_SEM_Creat 功能描述  : 创建信号量 输入参数  : IN ikey  信号量键值 输出参数  : 无  返 回 值  : int 调用函数  :  被调函数  :   修改历史      :  1.日    期   : 2012年5月18日星期五    作    者   : zhangjinlei    修改内容   : 新生成函数*****************************************************************************/int DRV_APP_SEM_Creat(IN const key_t ikey){    int iSemID;    union semun uSem;    uSem.pstBuffer = NULL;    uSem.pusArray= NULL;    uSem.iValue = 0;    /* 获取信号量ID号 */    iSemID = semget(ikey, 1, IPC_CREAT|0666);    if (-1 == iSemID)    {        printf("create semaphore error\n");        /* 推出进程 */        exit(-1);    }    /* 必须设置为1,否则第一次获取信号量失败 */    uSem.iValue = 1;        /* SETVAL: Set the value of semval to arg.val */    if (-1 == (semctl(iSemID, 0, SETVAL, uSem)))    {        printf("sem ctl error\n");        /* 推出进程 */        exit(-1);    }        return iSemID;}/***************************************************************************** 函 数 名  : DRV_APP_SEM_Delete 功能描述  : 删除信号量 输入参数  : int iSemID   输出参数  : 无 返 回 值  :  调用函数  :  被调函数  :   修改历史      :  1.日    期   : 2012年5月18日星期五    作    者   : zhangjinlei    修改内容   : 新生成函数*****************************************************************************/void DRV_APP_SEM_Delete(IN const int iSemID){    union semun uSem;    uSem.pstBuffer = NULL;    uSem.pusArray= NULL;    uSem.iValue = 0;    /* 删除信号量 */    if (-1 ==  (semctl(iSemID, 0, IPC_RMID, uSem)))    {        printf("sem ctl error\n");        /* 推出进程 */        exit(-1);    }}/***************************************************************************** 函 数 名  : DRV_APP_SEM_Passeren 功能描述  : 信号量使能 输入参数  : iSemID    信号量 输出参数  : 无 返 回 值  : int 调用函数  :  被调函数  :   修改历史      :  1.日    期   : 2012年5月18日星期五    作    者   : zhangjinlei    修改内容   : 新生成函数*****************************************************************************/int DRV_APP_SEM_Passeren(IN const int iSemID){    struct sembuf stSops;    stSops.sem_num = 0;    stSops.sem_op = -1;    stSops.sem_flg = SEM_UNDO;    /*      * 如果sem_op为正数,semop函数将该值加到相应的信号量元素中,     * 并唤醒所有等待元素增1的进程。如果sem_op为0而信号量的值不为0,      * semop将阻塞调用进程并增加那个元素的等零进程个数。如果sem_op为负数,     * semop将该值加到相应的信号量元素中(只要结果不为负数),如结果为负数,     * semop将阻塞进程等待信号量元素值增加     */    if (-1 == (semop(iSemID, &stSops, 1)))    {        printf("sem release error\n");        return -1;    }    return ERROR_SUCCESS;}/***************************************************************************** 函 数 名  : DRV_APP_SEM_Release 功能描述  : 信号量释放 输入参数  : iSemID    信号量 输出参数  : 无 返 回 值  : int 调用函数  :  被调函数  :   修改历史      :  1.日    期   : 2012年5月18日星期五    作    者   : zhangjinlei    修改内容   : 新生成函数*****************************************************************************/int DRV_APP_SEM_Release(int iSemID){    struct sembuf stSops;    stSops.sem_num = 0;    stSops.sem_op = 1;    stSops.sem_flg = SEM_UNDO;    /*      * 如果sem_op为正数,semop函数将该值加到相应的信号量元素中,     * 并唤醒所有等待元素增1的进程。如果sem_op为0而信号量的值不为0,      * semop将阻塞调用进程并增加那个元素的等零进程个数。如果sem_op为负数,     * semop将该值加到相应的信号量元素中(只要结果不为负数),如结果为负数,     * semop将阻塞进程等待信号量元素值增加     */         if (-1 == (semop(iSemID, &stSops, 1)))    {        printf("sem release error\n");        return -1;    }    return ERROR_SUCCESS;}/* END:   Added by zhangjinlei, 2012/5/18   PN: *//***************************************************************************** 函 数 名  : main 功能描述  : 内存共享主机端主程序 输入参数  : void 输出参数  : 无 返 回 值  : int 调用函数  :  被调函数  :   修改历史      :  1.日    期   : 2012年5月17日星期四    作    者   : zhangjinlei    修改内容   : 新生成函数*****************************************************************************/int main(IN const int iargc, OUT char **ppargv) {     key_t iKey;                             /* 消息队列对应的键值 */    key_t iReadSemKey;                             /* 消息队列对应的键值 */    key_t iWriteSemKey;                             /* 消息队列对应的键值 */    int iMsgID;                             /* 消息队列对应的ID值 */    const char cSendMsg[40]= "service send msg data!";    int iRet;    void *pTempAdd = NULL;    (void)iargc;    (void)ppargv;    printf("[app]mem share page size=%d\n", getpagesize());         if ((iKey = ftok(DRV_APP_MSG_QUE_FILE_NAME, 's')) == -1)     {         printf("[app]mem share Creat Key Error, ikey = %d, line = %d\n", iKey,  __LINE__);         return ERROR_FAILED;    }     /* BEGIN: Added by zhangjinlei, 2012/5/18 */        if ((iReadSemKey = ftok(DRV_APP_MSG_QUE_FILE_NAME, 'r')) == -1)     {         printf("[app]sem Creat Key Error, ikey = %d, line = %d\n", iReadSemKey,  __LINE__);         return ERROR_FAILED;    }         if ((iWriteSemKey = ftok(DRV_APP_MSG_QUE_FILE_NAME, 'w')) == -1)     {         printf("[app]sem Creat Key Error, ikey = %d, line = %d\n", iWriteSemKey,  __LINE__);         return ERROR_FAILED;    }         /* END:   Added by zhangjinlei, 2012/5/18   PN: */    /* 创建了20KB大小的共享内存空间 */    if((iMsgID = shmget(iKey, DRV_APP_SHARE_MEMORY_SIZE, 0666|IPC_CREAT )) == -1)     {        printf("Creat iMsgID Error, iMsgID = %d, line = %d\n", iMsgID, __LINE__);        return ERROR_FAILED;    }     /* 锁定该区域的内存 */    iRet = shmctl(iMsgID, SHM_LOCK, 0);      if(0 != iRet )     {        printf("[app]locked memory share failed, iRet = %d, line = %d\n", iRet, __LINE__);        return ERROR_FAILED;    }    pTempAdd = shmat(iMsgID, ( const void* )0, 0);      if (NULL == pTempAdd)    {        printf("[app]Get memory share failed, line = %d\n", __LINE__);         return ERROR_FAILED;    }    /* BEGIN: Added by zhangjinlei, 2012/5/18 */    g_iReadSemID = DRV_APP_SEM_Creat(iReadSemKey);    g_iWriteSemID = DRV_APP_SEM_Creat(iWriteSemKey);    /* END:   Added by zhangjinlei, 2012/5/18   PN: */        for (; ;)    {         /* BEGIN: Added by zhangjinlei, 2012/5/18 */        (void)DRV_APP_SEM_Passeren(g_iWriteSemID);        /* END:   Added by zhangjinlei, 2012/5/18   PN: */                (void)memcpy(pTempAdd, cSendMsg, sizeof(cSendMsg));        printf("[app]DRV_APP_SEM_Passeren , line = %d\n", __LINE__);         /* BEGIN: Added by zhangjinlei, 2012/5/18 */        (void)DRV_APP_SEM_Release(g_iReadSemID);        /* END:   Added by zhangjinlei, 2012/5/18   PN: */        (void)sleep(2);            }         #if 0    /* BEGIN: Added by zhangjinlei, 2012/5/18 */    v(semid);    /* END:   Added by zhangjinlei, 2012/5/18   PN: */    iRet = shmdt(pTempAdd);    if (0 != iRet)    {        printf("[app]Memory detached failed %d, line = %d\n", iRet, __LINE__);         return ERROR_FAILED;    }    #endif} 


服务器端:

/******************************************************************************                  版权所有 (C), 2001-2011,  ******************************************************************************  文 件 名   : drv_app_mem_slave.c  版 本 号   : 初稿  作    者   : zhangjinlei  生成日期   : 2012年5月16日星期三  最近修改   :  功能描述   : 内存共享客户端函数  函数列表   :              main  修改历史   :  1.日    期   : 2012年5月16日星期三    作    者   : zhangjinlei    修改内容   : 创建文件******************************************************************************//*----------------------------------------------* * 包含头文件                                   * *----------------------------------------------*/#include <stdio.h> #include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/ipc.h> #include <sys/shm.h>#include <sys/sem.h>#include "drv_app_common.h"/*----------------------------------------------* * 外部变量说明                                 * *----------------------------------------------*//*----------------------------------------------* * 外部函数原型说明                             * *----------------------------------------------*//*----------------------------------------------* * 内部函数原型说明                             * *----------------------------------------------*//*----------------------------------------------* * 全局变量                                     * *----------------------------------------------*/static int g_iReadSemID;static int g_iWriteSemID;/*----------------------------------------------* * 模块级变量                                   * *----------------------------------------------*//*----------------------------------------------* * 常量定义                                     * *----------------------------------------------*//*----------------------------------------------* * 宏定义                                       * *----------------------------------------------*/#define   DRV_APP_MSG_QUE_FILE_NAME "."                  /* 消息队列指定文件名 */#define   DRV_APP_SHARE_MEMORY_SIZE 81920                /* 共享内存的大小 *//* BEGIN: Added by zhangjinlei, 2012/5/18 */union semun { int iValue; struct semid_ds *pstBuffer; unsigned short *pusArray;}arg;/***************************************************************************** 函 数 名  : DRV_APP_SEM_Creat 功能描述  : 创建信号量 输入参数  : IN ikey  信号量键值 输出参数  : 无  返 回 值  : int 调用函数  :  被调函数  :   修改历史      :  1.日    期   : 2012年5月18日星期五    作    者   : zhangjinlei    修改内容   : 新生成函数*****************************************************************************/int DRV_APP_SEM_Creat(IN const key_t ikey){    int iSemID;    union semun uSem;    uSem.pstBuffer = NULL;    uSem.pusArray= NULL;    uSem.iValue = 0;    /* 获取信号量ID号 */    iSemID = semget(ikey, 1, IPC_CREAT|0666);    if (-1 == iSemID)    {        printf("create semaphore error\n");        /* 推出进程 */        exit(-1);    }    /* 必须设置为1,否则第一次获取信号量失败 */    uSem.iValue = 1;        /* SETVAL: Set the value of semval to arg.val */    if (-1 == (semctl(iSemID, 0, SETVAL, uSem)))    {        printf("sem ctl error\n");        /* 推出进程 */        exit(-1);    }        return iSemID;}//删除信号量/***************************************************************************** 函 数 名  : DRV_APP_SEM_Delete 功能描述  : 删除信号量 输入参数  : int iSemID   输出参数  : 无 返 回 值  :  调用函数  :  被调函数  :   修改历史      :  1.日    期   : 2012年5月18日星期五    作    者   : zhangjinlei    修改内容   : 新生成函数*****************************************************************************/void DRV_APP_SEM_Delete(IN const int iSemID){    union semun uSem;    uSem.pstBuffer = NULL;    uSem.pusArray= NULL;    uSem.iValue = 0;    /* 删除信号量 */    if (-1 ==  (semctl(iSemID, 0, IPC_RMID, uSem)))    {        printf("sem ctl error\n");        /* 推出进程 */        exit(-1);    }}/***************************************************************************** 函 数 名  : DRV_APP_SEM_Passeren 功能描述  : 信号量使能 输入参数  : iSemID    信号量 输出参数  : 无 返 回 值  : int 调用函数  :  被调函数  :   修改历史      :  1.日    期   : 2012年5月18日星期五    作    者   : zhangjinlei    修改内容   : 新生成函数*****************************************************************************/int DRV_APP_SEM_Passeren(IN const int iSemID){    struct sembuf stSops;    stSops.sem_num = 0;    stSops.sem_op = -1;    stSops.sem_flg = SEM_UNDO;    /*      * 如果sem_op为正数,semop函数将该值加到相应的信号量元素中,     * 并唤醒所有等待元素增1的进程。如果sem_op为0而信号量的值不为0,      * semop将阻塞调用进程并增加那个元素的等零进程个数。如果sem_op为负数,     * semop将该值加到相应的信号量元素中(只要结果不为负数),如结果为负数,     * semop将阻塞进程等待信号量元素值增加     */    if (-1 == (semop(iSemID, &stSops, 1)))    {        printf("sem release error\n");        return -1;    }    return ERROR_SUCCESS;}/***************************************************************************** 函 数 名  : DRV_APP_SEM_Release 功能描述  : 信号量释放 输入参数  : iSemID    信号量 输出参数  : 无 返 回 值  : int 调用函数  :  被调函数  :   修改历史      :  1.日    期   : 2012年5月18日星期五    作    者   : zhangjinlei    修改内容   : 新生成函数*****************************************************************************/int DRV_APP_SEM_Release(int iSemID){    struct sembuf stSops;    stSops.sem_num = 0;    stSops.sem_op = 1;    stSops.sem_flg = SEM_UNDO;    /*      * 如果sem_op为正数,semop函数将该值加到相应的信号量元素中,     * 并唤醒所有等待元素增1的进程。如果sem_op为0而信号量的值不为0,      * semop将阻塞调用进程并增加那个元素的等零进程个数。如果sem_op为负数,     * semop将该值加到相应的信号量元素中(只要结果不为负数),如结果为负数,     * semop将阻塞进程等待信号量元素值增加     */         if (-1 == (semop(iSemID, &stSops, 1)))    {        printf("sem release error\n");        return -1;    }    return ERROR_SUCCESS;}/* END:   Added by zhangjinlei, 2012/5/18   PN: *//***************************************************************************** 函 数 名  : main 功能描述  : 内存共享客户端主函数 输入参数  : void 输出参数  : 无 返 回 值  : ERROR_SUCCESS   :表示函数执行成功             ERROR_FAILED    :表示函数执行失败  修改历史      :  1.日    期   : 2012年5月16日星期三    作    者   : zhangjinlei    修改内容   : 新生成函数*****************************************************************************/int main(IN const int iargc, OUT char **ppargv) {     key_t iKey;                             /* 消息队列对应的键值 */    key_t iReadSemKey;                             /* 消息队列对应的键值 */    key_t iWriteSemKey;                             /* 消息队列对应的键值 */    int iMsgID;                             /* 消息队列对应的ID值 */    char cSendMsg[40]= "service send msg data!";    int iRet;    const void *pTempAdd = NULL;    (void)iargc;    (void)ppargv;    printf("[app]mem share page size=%d\n", getpagesize());         if ((iKey = ftok(DRV_APP_MSG_QUE_FILE_NAME, 's')) == -1)     {         printf("[app]mem share Creat Key Error, ikey = %d, line = %d\n", iKey,  __LINE__);         return ERROR_FAILED;    }     /* BEGIN: Added by zhangjinlei, 2012/5/18 */    if ((iReadSemKey = ftok(DRV_APP_MSG_QUE_FILE_NAME, 'r')) == -1)     {         printf("[app]sem Creat Key Error, iReadSemKey = %d, line = %d\n", iReadSemKey,  __LINE__);         return ERROR_FAILED;    }      if ((iWriteSemKey = ftok(DRV_APP_MSG_QUE_FILE_NAME, 'w')) == -1)     {         printf("[app]sem Creat Key Error, iWriteSemKey = %d, line = %d\n", iWriteSemKey,  __LINE__);         return ERROR_FAILED;    }     /* END:   Added by zhangjinlei, 2012/5/18   PN: */        /* 创建了20KB大小的共享内存空间 */    if((iMsgID = shmget(iKey, DRV_APP_SHARE_MEMORY_SIZE, 0666|IPC_CREAT )) == -1)     {        printf("Creat iMsgID Error, iMsgID = %d, line = %d\n", iMsgID, __LINE__);        return ERROR_FAILED;    }     /* 锁定该区域的内存 */    iRet = shmctl(iMsgID, SHM_LOCK, 0);      if(0 != iRet )     {        printf("[app]locked memory share failed, iRet = %d, line = %d\n", iRet, __LINE__);        return ERROR_FAILED;    }    pTempAdd = shmat(iMsgID, ( const void* )0, 0);      if (NULL == pTempAdd)    {        printf("[app]Get memory share failed, line = %d\n", __LINE__);         return ERROR_FAILED;    }    /* BEGIN: Added by zhangjinlei, 2012/5/18 */    g_iReadSemID = DRV_APP_SEM_Creat(iReadSemKey);    g_iWriteSemID = DRV_APP_SEM_Creat(iWriteSemKey);    /* END:   Added by zhangjinlei, 2012/5/18   PN: */        for (; ;)    {         /* BEGIN: Added by zhangjinlei, 2012/5/18 */        (void)DRV_APP_SEM_Passeren(g_iReadSemID);        /* END:   Added by zhangjinlei, 2012/5/18   PN: */        (void)memcpy(cSendMsg, pTempAdd, sizeof(cSendMsg));        /* BEGIN: Added by zhangjinlei, 2012/5/18 */        (void)DRV_APP_SEM_Release(g_iWriteSemID);        /* END:   Added by zhangjinlei, 2012/5/18   PN: */                printf("[app]read memory buffer msg is %s, line = %d\n", cSendMsg, __LINE__);                 (void)sleep(2);    } #if 0    iRet = shmdt(pTempAdd);    if (0 != iRet)    {        printf("[app]Memory detached failed %d, line = %d\n", iRet, __LINE__);         return ERROR_FAILED;    }#endif} 


公共文件:

/******************************************************************************                  版权所有 (C), 2001-2011,  ******************************************************************************  文 件 名   : drv_app_common.h  版 本 号   : 初稿  作    者   : zhangjinlei  生成日期   : 2012年5月16日星期三  最近修改   :  功能描述   : drv_app_common.h 的头文件  函数列表   :  修改历史   :  1.日    期   : 2012年5月16日星期三    作    者   : zhangjinlei    修改内容   : 创建文件******************************************************************************/#ifndef __DRV_APP_COMMON_H__#define __DRV_APP_COMMON_H__#ifdef __cplusplus#if __cplusplusextern "C"{#endif#endif /* __cplusplus *//*----------------------------------------------* * 包含头文件                                   * *----------------------------------------------*//*----------------------------------------------* * 外部变量说明                                 * *----------------------------------------------*//*----------------------------------------------* * 外部函数原型说明                             * *----------------------------------------------*//*----------------------------------------------* * 内部函数原型说明                             * *----------------------------------------------*//*----------------------------------------------* * 全局变量                                     * *----------------------------------------------*//*----------------------------------------------* * 模块级变量                                   * *----------------------------------------------*//*----------------------------------------------* * 常量定义                                     * *----------------------------------------------*//*----------------------------------------------* * 宏定义                                       * *----------------------------------------------*/#define   IN #define   OUT#define   INOUT#define   ERROR_SUCCESS  0#define   ERROR_FAILED   1#define   DRV_APP_MSG_QUE_REPORT_TYPE  0x01   /* 报站器数据消息 */#define   DRV_APP_MSG_QUE_REPORT_BACK  0x02   /* App 模块回应报站器消息 */#ifdef __cplusplus#if __cplusplus}#endif#endif /* __cplusplus */#endif /* __DRV_APP_COMMON_H__ */


 

原创粉丝点击