共享内存:

申请一块内存区域,两个进程都可以访问,利用该区域实现进程之间传递信息。

需要将共享的内存区域映射到自己的地址空间;

进程读写映射的空间相当于读写内存空间。

共享内存的操作机制没有阻塞机制;同步控制比较空难。

使用结束后需要解除映射,释放共享内存

实现步骤:

申请共享内存:

头文件:sys/shm.h     sys/ipc.h

int shmget(key_t key,size_t size,int shmflg);

函数功能:创建一个共享内存对象并返回共享内存标识符;如已存在共享内存则返回内存标识符。

参数:key:会建立新的共享内存对象,是一个大于0的32位整数,通常要求此值来源于ftok

返回的IPC键值;

           size:大于0的整数;表示新建内存的大小,以字节为单位;

           shmflg:0,共享内存标识符,若不存在则函数会报错;
                          IPC_CREAT:当shmflg&IPC_CREAT为真时,如果内核中不存在键值与key相

                         等的共享内存,则新建一个共享内存;如果存在这样的共享内存,返回此共享内

                         存的标识符;
                         IPC_CREAT|IPC_EXCL:如果内核中不存在键值与key相等的共享内存,则新建

                        一个共享内存;如果存在这样的共享内存则报错。
                        使用时需要与IPC对象存取权限(如0600)进行|运算来确定信号量集的存取权限。

        成功:返回共享内存的标识符;失败:返回-1,错误原因存于error中。

映射共享内存:

void *shmat(int shmid,const void *shmaddr,int shmflg);

        功能:连接共享内存标识符为shmid的共享内存,连接成功后把共享内存区映射到调用进程的

                   地址空间,随后可以像访问本地空间一样进行访问;

        参数:shmid:共享内存标识符;

                    shmaddr:指定共享内存出现在进程内存地址的什么位置,直接指定为NULL可以让内

核自己确定一个合适的地址位置;

                    shmflg:SHM_RDONLY:为只读模式,其他为读写模式。可以直接写0。

        返回值:成功:附加好的共享内存地址;出错:返回-1,错误原因存于error中。

 

解除映射:

int shmaddr(const void *shmaddr);

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

                   存,本函数调用并不删除所指定的共享内存区,而只是将先前用shmat函数(attach)

                   好的共享内存脱离(detach)目前的进程。Int shmdt(const void *shmaddr);

        参数:shmaddr:连接的共享内存的起始地址

        返回值:成功:返回0;出错:返回-1,错误原因存于error中

释放:

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

        功能:释放共享内存;

        参数:1.shmid:共享内存标识符;
                   2.cmd:IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf

                   中;
                   IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode

                   复制到共享内存的shmid_ds结构内;
                   IPC_RMID:删除这片共享内存。
                   3.buf:共享内存管理结构体。具体说明参见共享内存内核结构定义部分。

        成功:返回0;出错:返回-1,错误原因存于error中。

创建共享内存,往共享内存中写数据:

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

int main()
{
	int shmid = 0;
	char *addr = NULL;
	key_t key = 0;
	int bre = 0;
    int release = 0;

	key = ftok("/home/feng/fengfeng/",1);

	shmid = shmget(key,2048,IPC_CREAT|0600);
	if(shmid < 0)
	{
		perror("shmget");
		exit(-1);
	}

	addr = shmat(shmid,NULL,0);
	if(addr < 0)
	{
		perror("shmat");
		exit(-1);
	}


	strcpy(addr,"hello world");

		
	bre = shmdt(addr);
	if(bre < 0)
	{
		perror("shmdt");
		exit(-1);
	}

	release = shmctl(shmid,IPC_RMID,NULL);
	if(release < 0)
	{
		perror("shmctl");
		exit(-1);
	}

	return 0;

}

从共享内存读数据:

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

int main()
{
	int shmid = 0;
	char *p = NULL;
	key_t key = 0;
	int ret = 0;
	char buf[1024] = {0};

	key = ftok("/home/hua/huahua/",1);

	shmid = shmget(key,1024,IPC_CREAT|0600);
	if(shmid < 0)
	{
		perror("shmget");
		exit(-1);
	}

	p = shmat(shmid,NULL,0);
	if(p < 0)
	{
		perror("shmat");
		exit(-1);
	}

	strcpy(buf,p);

	printf("buf is %s\n",buf);	
	
	ret = shmdt(p);
	if(ret < 0)
	{
		perror("shmdt");
		exit(-1);
	}


	return 0;

}

Logo

更多推荐