linux下共享内存

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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

即可每次启动时把共享内存修改为256MB

Sndchar.c

#include

#include

#include

#include

#include

#include

#include

#define SHAREDATABASE 115 /*shared memory database key*/

#define SHAREBUFFER 116 /*shared buffer key*/

#define SHAREMEMORY 0x800000

#define MAX_TEXT 512

struct 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 DataBase

if(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 Point

pchdatabaseori=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

#include

#include

#include

#include

#include

#include

相关文档
最新文档