Linux进程通讯之一:共享内存
2013-12-16 18:30
330 查看
应用级代码说话。操作共享内存,就和操作已知的内存一样(可以想象直接读写一个可知的结构体)。
本demo参考了lgui中内存共享的代码。在lgui中,画笔/画板之类需要全局共用的都放在共享区。
在共享区内,每个结构体有自己的index方便读写。
demo分为server/client,直接在Linux下运行即可。
1 共同的代码
semaphore.h
semaphore.cpp
shmem.h
2 client端
3 server端
本demo参考了lgui中内存共享的代码。在lgui中,画笔/画板之类需要全局共用的都放在共享区。
在共享区内,每个结构体有自己的index方便读写。
demo分为server/client,直接在Linux下运行即可。
1 共同的代码
semaphore.h
#ifndef __SEMAPHORE_H__ #define __SEMAPHORE_H__ #include <sys/sem.h> #ifdef __cplusplus extern "C" { #endif union semun{ int val; struct semid_ds* buf; unsigned short int *array; }; int sem_create(key_t sem_id); void sem_lock(int sem_set_id); void sem_unlock(int sem_set_id); void sem_remove(int sem_set_id); #ifdef __cplusplus } #endif /* __cplusplus */ #endif
semaphore.cpp
#include <sys/types.h> #include "semaphore.h" //create semaphore int sem_create(key_t sem_id) { union semun sem_val; int sem_set_id; int rc; sem_set_id=semget(sem_id,1,IPC_CREAT | 0600); if(sem_set_id==-1) { return -1; } sem_val.val=1; rc=semctl(sem_set_id,0,SETVAL,sem_val); if(rc==-1) { return -1; } else { return sem_set_id; } } //Lock void sem_lock(int sem_set_id) { struct sembuf sem_op; sem_op.sem_num =0; sem_op.sem_op =-1; sem_op.sem_flg =0; semop(sem_set_id,&sem_op,1); } //unlock void sem_unlock(int sem_set_id) { struct sembuf sem_op; sem_op.sem_num =0; sem_op.sem_op =1; sem_op.sem_flg =0; semop(sem_set_id,&sem_op,1); } //destroy void sem_remove(int sem_set_id) { semctl(sem_set_id,0,IPC_RMID); }
shmem.h
#ifndef __SHMEM_H__ #define __SHMEM_H__ #ifdef __cplusplus extern "C" { #endif #define SHMEM_SIZE 1024*1024 #define SHMEM_CGI_SIZE 4*1024 //index 4k #define SHMEM_CGI_OFFSET_INDEX 0 #define SHMEM_CGI_OFFSET_0 SHMEM_CGI_SIZE #define SHMEM_CGI_OFFSET_1 SHMEM_CGI_SIZE + SHMEM_CGI_SIZE //cgi为client #define SHMEM_SERVER 1 #define SHMEM_CLIENT 0 #define SHMEM_CS SHMEM_SERVER typedef int BOOL; typedef void *PVOID,*LPVOID; typedef PVOID HVODIOBJ; typedef PVOID HCGI; typedef struct _CgiCmdTag { int cmdindex; int cmd0; int cmd1; int cmd2; int cmd3; int cmdsize; char cmdname[20]; }CgiCmdTag,*pCgiCmdTag; BOOL InitShareMemServer(); BOOL InitShareMemClient(); void UnInitShareMem(int cs); int shm_read(char* pDest, int iOffset, int iLen); int shm_write(char* pSource, int iOffset, int iLen); char* GetShmAddr(); void LockShMem(); void UnLockShMem(); #ifdef __cplusplus } #endif /* __cplusplus */ #endifshmem.cpp
#include "semaphore.h" #include "shmem.h" #include <stdlib.h> #include <malloc.h> #include <string.h> #include <sys/shm.h> #define SEM_ID 250 #define SHMEM_ID 100 //#define SHMEM_FLAG IPC_CREAT | 0600 #define SHMEM_FLAG IPC_CREAT | 0666 int sem_set_id; int shm_id; char* pShmCgi; char* GetShmAddr() { return pShmCgi; } int shm_read(char* pDest, int iOffset, int iLen) { memcpy(pDest,pShmCgi+iOffset,iLen); return 0; } int shm_write(char* pSource, int iOffset, int iLen) { memcpy(pShmCgi+iOffset,pSource,iLen); return 0; } BOOL InitShareMemServer() { struct shmid_ds shm_desc; sem_set_id=sem_create(SEM_ID); if(sem_set_id == -1) { return false; } shm_id = shmget(SHMEM_ID,SHMEM_SIZE,SHMEM_FLAG); if(shm_id == -1) { sem_remove(sem_set_id); return false; } pShmCgi = (char*)shmat(shm_id,NULL,0); if(!pShmCgi) { sem_remove(sem_set_id); shmctl(shm_id,IPC_RMID,&shm_desc); return false; } return true; } BOOL InitShareMemClient() { struct shmid_ds shm_desc; shm_id = shmget(SHMEM_ID,SHMEM_SIZE,SHMEM_FLAG); if(shm_id == -1) { sem_remove(sem_set_id); return false; } pShmCgi = (char*)shmat(shm_id,NULL,0); if(!pShmCgi) { sem_remove(sem_set_id); shmctl(shm_id,IPC_RMID,&shm_desc); return false; } return true; } void UnInitShareMem(int cs) { struct shmid_ds shm_desc; if(cs) { sem_remove(sem_set_id); shmdt(pShmCgi); shmctl(shm_id,IPC_RMID,&shm_desc); } else { shmdt(pShmCgi); } } void LockShMem() { sem_lock(sem_set_id); } void UnLockShMem() { sem_unlock(sem_set_id); }
2 client端
//cgi client #include <string.h> #include <unistd.h> #include <stdio.h> #include <malloc.h> #include "semaphore.h" #include "shmem.h" //g++ cgibin_client.cpp semaphore.cpp shmem.cpp -o client.bin //HCGI :CreateCgiObject()中的shm可能存储不同的数据结构 HCGI GetCgiObject(int index) { int CgiOffset; int CgiIndex; char *pname; char* pShmAddr; CgiCmdTag *pCgiCmd; pShmAddr = GetShmAddr(); if(!pShmAddr) { return NULL; } CgiOffset = *(((int*)(pShmAddr+SHMEM_CGI_OFFSET_INDEX))+index); //get cgi index shm_read((char*)(&CgiIndex),CgiOffset,sizeof(int)); pCgiCmd = (CgiCmdTag*)malloc(sizeof(CgiCmdTag)); if(!pCgiCmd) { return NULL; } shm_read((char*)pCgiCmd,CgiOffset,sizeof(CgiCmdTag)); return (HCGI)pCgiCmd; } int main(int argc, char **argv) { CgiCmdTag *pCgiCmd = NULL; InitShareMemClient(); while(1) { for(int i=0;i<2;i++) { pCgiCmd = (CgiCmdTag*)GetCgiObject(i); printf("cgicmd[%d]:\n",i); printf("cmdindex :0x%04x\n",pCgiCmd->cmdindex); printf("cmd0 :0x%04x\n",pCgiCmd->cmd0); printf("cmd1 :0x%04x\n",pCgiCmd->cmd1); printf("cmd2 :0x%04x\n",pCgiCmd->cmd2); printf("cmd3 :0x%04x\n",pCgiCmd->cmd3); printf("cmdsize :0x%04x\n",pCgiCmd->cmdsize); printf("cmdname :%s\n",pCgiCmd->cmdname); printf("cgicmd[%d] print ok:\n\n",i); sleep(1); } } UnInitShareMem(SHMEM_CLIENT); printf( "UnInitShareMem ok\n" ); return 0; }
3 server端
//cgi server #include <string.h> #include <unistd.h> #include <stdio.h> #include <malloc.h> #include "semaphore.h" #include "shmem.h" //g++ cgibin_server.cpp semaphore.cpp shmem.cpp -o server.bin BOOL CreateCgiObject() { char* pShmAddr; int* pIdxAddr; int CgiOffset; CgiCmdTag CgiCmd0; CgiCmdTag CgiCmd1; pShmAddr = GetShmAddr(); if(!pShmAddr) { return false; } pIdxAddr = (int*)(pShmAddr+SHMEM_CGI_OFFSET_INDEX); //CgiCmd0 CgiOffset = SHMEM_CGI_OFFSET_0; CgiCmd0.cmdindex = 0x0000; CgiCmd0.cmd0 = 0x8000; CgiCmd0.cmd1 = 0x8001; CgiCmd0.cmd2 = 0x8002; CgiCmd0.cmd3 = 0x8003; CgiCmd0.cmdsize = 0x8004; memcpy(CgiCmd0.cmdname,"CgiCmd0",sizeof(CgiCmd0.cmdname)); memcpy((void*)(pShmAddr+CgiOffset),&CgiCmd0,sizeof(CgiCmd0)); *(pIdxAddr+CgiCmd0.cmdindex) = CgiOffset; //CgiCmd1 CgiOffset = SHMEM_CGI_OFFSET_1; CgiCmd1.cmdindex = 0x0001; CgiCmd1.cmd0 = 0x9000; CgiCmd1.cmd1 = 0x9001; CgiCmd1.cmd2 = 0x9002; CgiCmd1.cmd3 = 0x9003; CgiCmd1.cmdsize = 0x9004; memcpy(CgiCmd1.cmdname,"CgiCmd1",sizeof(CgiCmd0.cmdname)); memcpy((void*)(pShmAddr+CgiOffset),&CgiCmd1,sizeof(CgiCmd1)); *(pIdxAddr+CgiCmd1.cmdindex) = CgiOffset; CgiOffset = CgiOffset + SHMEM_CGI_SIZE; return true; } //HCGI :CreateCgiObject()中的shm可能存储不同的数据结构 HCGI GetCgiObject(int index) { int CgiOffset; int CgiIndex; char *pname; char* pShmAddr; CgiCmdTag *pCgiCmd; pShmAddr = GetShmAddr(); if(!pShmAddr) { return NULL; } CgiOffset = *(((int*)(pShmAddr+SHMEM_CGI_OFFSET_INDEX))+index); //get cgi index shm_read((char*)(&CgiIndex),CgiOffset,sizeof(int)); pCgiCmd = (CgiCmdTag*)malloc(sizeof(CgiCmdTag)); if(!pCgiCmd) { return NULL; } shm_read((char*)pCgiCmd,CgiOffset,sizeof(CgiCmdTag)); return (HCGI)pCgiCmd; } int SetCgiObject(int index) { CgiCmdTag *pCgiCmd = NULL; pCgiCmd = (CgiCmdTag*)GetCgiObject(index); char* pShmAddr; pShmAddr = GetShmAddr(); if(index==0) { pCgiCmd->cmdindex = 0; pCgiCmd->cmd0 = 0xa000; pCgiCmd->cmd1 = 0xa001; pCgiCmd->cmd2 = 0xa002; pCgiCmd->cmd3 = 0xa003; //pCgiCmd->cmdsize = 0xa000 + 1<<(index+1)+4; shm_write((char*)pCgiCmd,SHMEM_CGI_OFFSET_0,sizeof(CgiCmdTag)); } if(index==1) { pCgiCmd->cmdindex = 1; pCgiCmd->cmd0 = 0xb000; pCgiCmd->cmd1 = 0xb001; pCgiCmd->cmd2 = 0xb002; pCgiCmd->cmd3 = 0xb003; //pCgiCmd->cmdsize = 0xb000 + 1<<(index+1)+4; memcpy(pCgiCmd->cmdname,"CgiCmd1_Modify",sizeof(pCgiCmd->cmdname)); shm_write((char*)pCgiCmd,SHMEM_CGI_OFFSET_1,sizeof(CgiCmdTag)); } } int main(int argc, char **argv) { InitShareMemServer(); CreateCgiObject(); printf("CreateCgiObject ok\n"); sleep(10); SetCgiObject(0); SetCgiObject(1); printf("SetCgiObject ok\n"); sleep(20); UnInitShareMem(SHMEM_SERVER); printf( "UnInitShareMem ok\n" ); return 0; }
相关文章推荐
- Linux 进程间通讯之共享内存方式
- linux 进程间通讯-共享内存
- Unix/linux 进程间通讯 - 共享内存
- linux进程通讯-共享内存
- Linux进程间通讯之共享内存
- [Linux学习]Linux下进程通讯之共享内存
- Linux 进程间通讯之共享内存方式
- linux进程通讯-共享内存http://doc.chinaunix.net/linux/201010/996044.shtml
- linux进程通讯-共享内存
- Linux笔记_进程通讯——共享内存
- Linux进程通讯:管道通讯、信号通讯、共享内存
- linux进程通讯-共享内存1
- linux进程间通讯-共享内存
- linux进程通讯-共享内存
- Linux进程同步与通讯:共享内存和信号量的使用
- Linux进程间通讯之共享内存
- Linux进程间通讯五--共享内存
- (4)linux进程通讯之共享内存
- linux进程通讯-共享内存
- Linux下进程间共享内存编码方式入门