Linux---进程间通信之————共享内存

共享内存:

        是被多个进程共享的一部分物理内存.共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容.

共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。两个不同的进程AB共享内存的意思是,同一块物理内存被映射到进程AB各自的进程地址空间,进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以。

  采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的复制。对于像管道和消息队列等通信方式,则需要内核和用户空间进行四次的数据复制,而共享内存则只复制两次数据:一次从输入文件到共享内存区,另一次从共享内存区到输出文件。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,在重新建立共享内存区域,而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件。共享内存中的内容往往是在解除映射时才写回文件的。因此,采用共享内存的通信方式效率是非常高的。

 

共享内存实现分为两个步骤:

 1、创建共享、打开共享内存,使用shmget函数

 2、映射共享内存,将这段创建的共享内存映射到具体的进程空间去,使用shmat函数

          3. 分离共享内存

          4. 控制、删除共享内存

 

创建共享内存

Shmgt()

函数的作用:在内核中创建共享内存

函数的原型:int shmgt(key_t key,  int size,  int shmflg);

函数的头文件:#include <sys/types.h>#include <sys/shm.h>

函数的参数:

       Keykey标识共享内存的键值: 0/IPC_PRIVATE。 当key的取值为IPC_PRIVATE,则函 数shmget()将创建一块新的共享内存;如果key的取值为0,而参数shmflg中又设置IPC_PRIVATE这个标志,则同样会创建一块新的共享内存.

       Size:创建的内存的大小。

       Shmflg:类似open的权限。

函数逇返回值:

          成功:返回共享内存段标识符。

          出错:返回 -1.


映射共享内存

Shmat()

函数的作用:映射共享内存,映射到各自的内存空间。

函数的原型:char *shmat(int shmid,  char * shmaddr,  int flag);

函数的头文件:#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>

函数的参数:

          Shmid:内存标识符

    Shmaddr:映射共享内存到本进程的指定地址,如果为NULL则由内核进行

                    自动分配。

          FlagSHM_RDONLY:表示共享内存只读。

                0:表示共享内存可读写。

函数的返回值:

          成功:返回共享内存映射到进程中的地址。

          出错:返回 -1

 当一个进程不再需要共享内存时,需要把它从进程地址空间中脱离。

 

共享内存解除映射

Shmdt()

函数的作用:撤销共享内存的映射。

函数的原型:int shmat(const void *shmaddr);

函数的参数:

          Shmaddr:被映射的共享内存地址。

函数的返回值:

          成功:返回0

          出错:返回-1.

实例代码:

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

#define PERM S_IRUSR|S_IWUSR
/*shared-memory */

int main(int argc,char **argv) 
{ 
	int shmid; 
	char *p_addr,*c_addr; 
	
	if(argc!=2) 
	{ 
		fprintf(stderr,"Usage:%s\n\a",argv[0]); 
		exit(1); 
	}

	/*creat shared-memory */	
	if((shmid=shmget(IPC_PRIVATE,1024,PERM))==-1) 
	{ 
		fprintf(stderr,"Create Share Memory Error:%s\n\a",strerror(errno)); 
		exit(1); 
	} 

	/*creat child fork */
	if(fork()) /*father fork write*/ 
	{ 
		p_addr=shmat(shmid,0,0); 
		memset(p_addr,'\0',1024); 
		strncpy(p_addr,argv[1],1024);
		wait(NULL); /*release resource,  no care of end state*/ 
		exit(0); 
	} 
	else       /*child fork read*/ 
	{ 
		sleep(1); /*stop 1s*/ 		
		c_addr=shmat(shmid,0,0); 
		printf("Client get %s\n",c_addr); 
		exit(0); 
	} 
} 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值