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__ */
- linux 共享内存消息队列使用
- linux 共享内存 消息队列 udp通信
- Linux 内存共享与消息队列
- Linux信号量 共享内存和消息队列
- Linux C 消息队列和共享内存
- linux 信号量、共享内存、和消息队列
- Linux 消息队列、共享内存、信号量(一)消息队列
- Linux c 基于内存的进程通信—共享内存、共享队列(消息队列)
- 信号量 消息队列 共享内存
- 管道/消息队列/共享内存
- 信号量、消息队列、共享内存
- 【转】linux的消息队列与共享内存编程
- Linux程序设计——信号量、共享内存和消息队列
- [Linux] 第 14 章 信号量,共享内存和消息队列
- linux 管道、消息队列、共享内存的对比
- linux 消息队列 和 内存共享的简短说明
- 《Linux程序设计》——信号量、共享内存和消息队列
- Linux Programing -- ch14-- 信号量、共享内存、消息队列
- 常见设计模式的解析和实现(C++)之三-Builder模式
- “火柴棍式”程序员面试题
- C#(Visual Studio)颜色设置
- 不用编程,能直接计算正确么?
- 【Android 开发教程】DatePicker
- linux 共享内存消息队列使用
- 卡片布局的一个很好的应用
- inno setup 安装 .net 服务
- 两个程序块在不同情况下哪个更快
- 可以继承的C++ Singleton基类
- Css margin 对各浏览器支持的解决方法
- 一位前辈工程师职业发展的忠告
- 常见设计模式的解析和实现(C++)之四-Prototype模式
- JPCAP