当前位置:文档之家› linux下共享内存

linux下共享内存

Linux下共享内存SUNNY.MAN共享内存允许两个或多个进程进程共享同一块内存(这块内存会映射到各个进程自己独立的地址空间) 从而使得这些进程可以相互通信,进程退出时会自动和已经挂接的共享内存区段分离,但是仍建议当进程不再使用共享区段时调用shmdt来卸载区段。

注意,当一个进程分支出父进程和子进程时,父进程先前创建的所有共享内存区段都会被子进程继承。

如果区段已经做了删除标记(在前面以IPC_RMID指令调用shmctl),而当前挂接数已经变为0,这个区段就会被移除。

Linux中通过API函数shmget创建的共享内存一般都是在程序中使用shmctl来释放的,但是有时为了调试程序,开发人员可能通过Ctrl + C等方式发送中断信号来结束程序,此时程序申请的共享内存就不能得到释放,当然如果程序没有改动的话,重新运行程序时仍然会使用上次申请的共享内存,但是如果我们修改了程序,由于共享内存的大小不一致等原因会导致程序申请共享内存错误。

因此,我们总是希望每次结束时就能释放掉申请的共享内存。

有两种方法可以用来释放共享内存:第一种:如果总是通过Crtl+C来结束的话,可以做一个信号处理器,当接收到这个信号的时候,先释放共享内存,然后退出程序。

第二种:不管你以什么方式结束程序,如果共享内存还是得不到释放,那么可以通过linux命令ipcrm shm shmid来释放,在使用该命令之前可以通过ipcs -m命令来查看共享内存。

共享内存查看使用ipcs命令,不加如何参数时,会把共享内存、信号量、消息队列的信息都打印出来,如果只想显示共享内存信息,使用如下命令:[root@localhost ~]# ipcs –m同样共享内存的大小也可以用ipcs –lm来查看它的上限下限。

shmget( ) 创建一个新的共享内存区段取得一个共享内存区段的描述符shmctl( ) 取得一个共享内存区段的信息为一个共享内存区段设置特定的信息移除一个共享内存区段shmat( ) 挂接一个共享内存区段shmdt( ) 于一个共享内存区段的分离同样共享内存的大小也可以用ipcs –lm来查看它的上限下限。

我们主要也是关心三个变量,一个是一共可以建立多少个共享内存段,每个段都大可以多少,一共有多少内存可以共享。

使用下面的命令查看共享内存的大小:max number of segments = 4096//总共可以有多少个段max seg size (kbytes) = 4194303//一个段可以多大max total shared memory (kbytes) = 1073741824//所有可以共享的内存大小min seg size (bytes) =1# cat /proc/sys/kernel/shmmax修改共享内存大小:临时修改:在root用户下执行# echo 268435456 > /proc/sys/kernel/shmmax把共享内存大小设置为256MB;永久修改:在root用户下修改/etc/rc.d/rc.local文件,加入下面一行:echo 268435456 > /proc/sys/kernel/shmmax即可每次启动时把共享内存修改为256MBSndchar.c#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/sem.h>#include<sys/shm.h>#include<errno.h>#include<unistd.h>#define SHAREDATABASE 115 /*shared memory database key*/#define SHAREBUFFER 116 /*shared buffer key*/#define SHAREMEMORY 0x800000#define MAX_TEXT 512struct strshm{long head;long tail;};int main(void){int shm_id;int running=1;char *pchdatabase=NULL;char *pchdatabaseori=NULL;struct strshm * phead=NULL;char buffer[MAX_TEXT];long res=0;shm_id=shmget(SHAREDATABASE,SHAREMEMORY,IPC_CREAT);//Create DataBaseif(shm_id==-1){fprintf(stderr,"shmget failed with error: %d\n",errno);exit(EXIT_FAILURE);}else{printf("shmget success shmid is %d\n",shm_id);}pchdatabase=(char*)shmat(shm_id,0,0); //Get Pointpchdatabaseori=pchdatabase;phead=(struct strshm *)pchdatabase;pchdatabase+=sizeof(struct strshm);phead->head=sizeof(struct strshm);phead->tail=sizeof(struct strshm);while(running){memset(buffer,0,MAX_TEXT);printf("Enter some text: less than %d [type end stop]\n",MAX_TEXT);fgets(buffer, MAX_TEXT, stdin);res=strlen(buffer)+sizeof(long)+1;//'\0'if((phead->head+res)<=(0x800000-sizeof(struct strshm))){(*(long *)(pchdatabase+phead->head))=res;phead->head+=sizeof(long);memcpy(pchdatabase+phead->head,buffer,res-sizeof(long));phead->head+=(res-sizeof(long));printf("current head is %d,insert len=%d\n",phead->head,res);}if(strncmp(buffer, "end", 3) == 0){break;}}if(shmdt(pchdatabaseori) == -1)perror(" detach error \n");shmctl(shm_id, IPC_RMID, NULL);return 0;}Rcvchar.c#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/sem.h>#include<sys/shm.h>#include<errno.h>#include<unistd.h>#define SHAREDATABASE 115 /*shared memory database key*/#define SHAREBUFFER 116 /*shared buffer key*/#define SHAREMEMORY 0x800000#define MAX_TEXT 512struct strshm{long head;long tail;};int main(void){int shm_id;int running=1;char *pchdatabase=NULL;char *pchdatabaseori=NULL;struct strshm * phead=NULL;char buffer[MAX_TEXT];long res=0;shm_id=shmget(SHAREDATABASE,SHAREMEMORY,IPC_CREAT);//Create DataBaseif(shm_id==-1){fprintf(stderr,"shmget failed with error: %d\n",errno);exit(EXIT_FAILURE);}else{printf("shmget success shmid is %d\n",shm_id);}pchdatabase=(char*)shmat(shm_id,0,0); //Get Pointpchdatabaseori=pchdatabase;phead=(struct strshm *)pchdatabase;pchdatabase+=sizeof(struct strshm);while(running){//phead=(struct strshm *)pchdatabaseori;memset(buffer,0,MAX_TEXT);if(phead->tail<phead->head){res=*((long *)(pchdatabase+phead->tail));memcpy(buffer,pchdatabase+phead->tail+sizeof(long),res-4);phead->tail+=res;printf("current tail is %d,get len=%d,content=%s\n",phead->tail,res,buffer);}if(strncmp(buffer, "end", 3) == 0){break;}usleep(300000);}if(shmdt(pchdatabaseori) == -1)perror(" detach error \n");shmctl(shm_id, IPC_RMID, NULL);return 0;}Makefileall:sndchar rcvcharsnd:sndchar.c$ gcc -g -o $@ $< >debug.txt 2>&1@echo 编译成功 $@rcv:rcvchar.c$ gcc -g -o $@ $< >>debug.txt 2>&1@echo 编译成功 $@clean:@rm -f sndchar@rm -f rcvchar@rm -f debug.txt关于共享内存,就这么多了,不过要想很好的使用共享内存,一定要考虑资源冲突与数据完整性的问题。

相关主题