进程间共享内存及其简单实例

一. 进程间通信
进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。进程通信根据交换信息量的多少和效率的高低,分为低级通信(只能传递状态和整数值)和高级通信(提高信号通信的效率,传递大量数据,减轻程序编制的复杂度)。高级通信的三种主要方式为:共享内存模式、消息传递模式、共享文件模式。
这里主要介绍共享内存模式实现方法和简单例子。

二. 进程间共享内存
基本函数:

创建或打开共享存储区(shmget)• 依据用户给出的整数值key,创建新区或打开现有区,返回一个共享存储区ID。
连接共享存储区(shmat)• 连接共享存储区到本进程的地址空间,可以指定虚拟地址或由系统分配,返回共享存储区首地址。父进程已连接的共享存储区可被fork创建的子进程继承。
拆除共享存储区连接(shmdt)拆除共享存储区与本进程地址空间的连接。
共享存储区控制(shmctl)• 对共享存储区进行控制。如:共享存储区的删除需要显式调用shmctl(shmid, IPC_RMID, 0);

创建共享存储区需要两个进程的IPC键值相同。
用系统调用ftok给出IPC键值key:保证同一个用户的两个进程获得相同IPC键值key,使用方法如下:
• ftok用于保证同一个用户的两个进程获得相同的IPC键值key;对于两个不同用户下的两组相同程序获得互不干扰的IPC键值。
• ftok的头文件:   
• #include <sys/types.h>   
• #include <sys/ipc.h>   
• ftok原型如下:   
• key_t ftok( char * fname, int id )   
• 其中
• fname就是你指定的文件名(已经存在的文件名),一般使用当前目录,如:   
• key_t key;   
• key = ftok(".", 1); //这里就是将fname设为当前目录。   
• id是子序号。
• 当删除重建文件后,ftok获得的key_t值会改变。   
• 如果要确保key_t值不变,要么确保ftok的文件不被删除,要么不用ftok,指定一个固定的key_t值。

三. 进程共享内存的简单例子
通过进程间共享内存,在子进程中形成斐波那契数列,在父进程中输出。代码实现如下:

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdlib.h>
#include<errno.h>
#define SIZE 1024
extern int errno;
int main(){
	int *fib;
	int n;
	int i=0;
	scanf("%d",&n);
	if(n<0) 
	printf("request a non-negative number!\n");   
	int shmid;
	key_t key;
	pid_t pid;
	int* shmptr;
	if((key = ftok(".", 1)) < 0){  #由ftok得到IPC键值
		printf("ftok error!\n");   
		return -1;
	}
	if((shmid = shmget(key, SIZE,IPC_CREAT | 0660)) < 0){        #创建共享存储区
			printf("shmget error!\n");
			exit(-1);
	}
	shmptr = (int*)shmat(shmid, NULL, 0);                #连接共享存储区
	fib = shmptr;                   #斐波那契数组的指针指向共享存储区地址,即共享该数组空间
	if(fib == (int*)(-1)){	
			printf("shmat error!\n");
			exit(-1);
	}
	pid = fork();
	if(pid<0){            #创建子进程失败
		printf("fork error!\n");
		return -1;
	}
	else if(pid==0){    #在子进程中
		fib[0]=0;
		fib[1]=1;
		for(i=2;i<n;++i){     #计算斐波那契数列
			fib[i]=fib[i-1]+fib[i-2]; 
		}
		if((shmctl(shmid, IPC_RMID, 0) < 0)){    #控制共享存储区
			printf("shmctl error!\n");
			exit(-1);
		}
		exit(0);
	}
	else{    #父进程
		wait(0);      #等待子进程结束
		for(i=0;i<n;++i)
			printf("%d ",fib[i]);
		printf("\n");	
		if(shmdt(fib)==-1){
			printf("shmdt error!\n");
			exit(-1);
		}
	}
	exit(0);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值