Linux编程实践----共享内存的演示(IPC)

来源:互联网 发布:来疯直播软件 编辑:程序博客网 时间:2024/05/22 07:02

Linux编程实践----共享内存的演示(IPC)

1.共享内存是允许两个不相关的进程访问同一个逻辑内存,其是进程之间共享数据的一种非常有效的方式;

一般使用时,是用共享内存来提供对大块内存的有效访问,用传递小消息来进行同步对该共享内存的访问!

 

2.共享内存函数由shmget、shmat、shmdt、shmctl四个函数组成。

 

函数名

头文件名

参数值意义

返回值

作用

int shmget(key_t key,size_t size,int shmflg)#include <sys/shm.h>

1.共享内存段的名字;

2.共享内存的大小;

3.IPC_CREAT:当shmflg&IPC_CREAT为真时,如果内核中不存在键值与key相等的共享内存,则新建一个共享内存;如果存在这样的共享内存,返回此共享内存的标识符;IPC_CREAT|IPC_EXCL:如果内核中不存在键值 与key相等的共享内存,则新建一个共享内存;如果存在这样的共享内存则报错

共享内存标识符;失败返回-1.

得到一个共享内存标识符或者是创建

一个共享内存对象并返回其标识符。

void *shmat(int shm_id,const void *shm_addr,int shmflg)#include <sys/shm.h>

1.共享内存标识符;

2.指定共享内存出现在进程内存地址的什么位置,直接指定为NULL让内核自己决定一个合适的地址位置。(自己指定,会造成应用程序对硬件的依赖性过高,最好是内核自己决定);

3.SHM_RDONLY:为只读模式,其他为读写模式

1.成功:附加好的共享内存地址

2.出错:-1,错误原因存于error中

连接标识符为shm_id的共享内存,成功后把共享内存对象映射到调用进程的地址空间,便可以访问了。

fork后子进程继承已连接的共享内存地址。exec后该子进程与已连接的共享内存地址自动脱离(detach)。进程结束后,已连接的共享内存地址会自动脱离(detach)。

int shmdt(const void * sjm_addr)#include <sys/shm.h>1.连接的共享内存的起始地址

1.成功返回0;

2.失败返回-1,原因存在于error中。

shmat函数相反,是用来断开与共享内存附加点的地址,禁止本进程访问此片共享内存。

本函数调用并不删除所指定的共享内存区,而只是将先前用shmat函数连接(attach)好的共享内存脱离(detach)目前的进程

int shmctl(int shm_id,int cmd,struct shmid_ds *buf)#include <sys/shm.h>

1.共享内存的标识符;

2.cmd:命令---IPC_STAT:把buf中的数据设置为当前共享内存的状态值;IPC_SET:把共享内存的当前状态设置为buf中给出的值,要求进程有一定的权限;IPC_RMID:删除共享内存段。

1.成功返回0;

2,失败返回-1,原因在于error中。

对共享内存的控制。

 

3.错误代码,可能出现的错误:

EACCESS:参数cmd为IPC_STAT,确无权限读取该共享内存
EFAULT:参数buf指向无效的内存地址
EIDRM:标识符为shmid的共享内存已被删除
EINVAL:无效的参数cmd或shmid
EPERM:参数cmd为IPC_SET或IPC_RMID,却无足够的权限执行

 

示例演示:

1.comm.h

using namespace std;class people{public:        int who;        int  age;};


2.创建共享内存,消费者,不断读取生产者写入的数据!

#include<unistd.h>#include<stdlib.h>#include<stdio.h>#include<sys/shm.h>#include<iostream>#include<string>using namespace std;#include"comm.h"int main(){        int running=1;        void *share_memory=(void *)0;        people *walker;        int shm_id=shmget((key_t)12,sizeof(people),0666 | IPC_CREAT);        if(shm_id<0)        {                cout<<"shmget failed!"<<endl;                exit(EXIT_FAILURE);        }        share_memory=shmat(shm_id,(void *)0,0);        if((long)share_memory<0)        {                cout<<"shmat failed"<<endl;                exit(EXIT_FAILURE);        }        cout<<(long)share_memory<<endl;        walker=(people *)share_memory;        walker->who=0;        int times=0;        while(running)        {                if(walker->who==1)                {                        cout<<"I am consumer ,OutputCurrent Age:"<<walker->age<<endl;                        sleep(3);                        walker->who=0;                        times++;                        if(times==3) running=0;                }        }        if(shmdt(share_memory)==-1)        {                cout<<"shmdt failed"<<endl;                exit(EXIT_FAILURE);        }         if(shmctl(shm_id,IPC_RMID,0)==-1)        {                cout<<"shmctl failed"<<endl;                exit(EXIT_FAILURE);        }        exit(EXIT_SUCCESS);}


 

3.生产者,不断向共享内存中写入数据!

#include<unistd.h>#include<stdlib.h>#include<stdio.h>#include<sys/shm.h>#include<iostream>#include<string>using namespace std;#include"comm.h"int main(){        int running=1;        void *share_memory=(void *)0;        people *walker;        int shm_id=shmget((key_t)12,sizeof(people),0666 | IPC_CREAT);        if(shm_id<0)        {                cout<<"shmget failed!"<<endl;                exit(EXIT_FAILURE);        }        share_memory=shmat(shm_id,(void *)0,0);        if((long)share_memory<0)        {                cout<<"shmat failed"<<endl;                exit(EXIT_FAILURE);        }        cout<<(long)share_memory<<endl;        walker=(people *)share_memory;        walker->who=0;        int times=0;        while(running)        {                if(walker->who==1)                {                        cout<<"I am consumer ,OutputCurrent Age:"<<walker->age<<endl;                        sleep(3);                        walker->who=0;                        times++;                        if(times==3) running=0;                }        }        if(shmdt(share_memory)==-1)        {                cout<<"shmdt failed"<<endl;                exit(EXIT_FAILURE);        }         if(shmctl(shm_id,IPC_RMID,0)==-1)        {                cout<<"shmctl failed"<<endl;                exit(EXIT_FAILURE);        }        exit(EXIT_SUCCESS);}

运行结果:

 


0 0
原创粉丝点击