Chinaunix首页 | 论坛 | 博客
  • 博客访问: 458763
  • 博文数量: 113
  • 博客积分: 446
  • 博客等级: 下士
  • 技术积分: 1229
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-09 16:01
个人简介

Let's go!!!!!

文章分类

全部博文(113)

文章存档

2019年(5)

2018年(4)

2017年(9)

2016年(5)

2015年(39)

2014年(6)

2013年(28)

2012年(17)

分类: LINUX

2012-12-11 12:34:59

共享存储
共享存储允许两个或更多进程共享一个给定的存储段。因为数据部需要在客户进程和服务进程之间复制,所以这是最快的一种IPC。使用共享存储时要掌握的唯一敲门时多个进程之间
对一个给定存储区的同步访问。若服务器进程正在将数据放入共享存储区,则在它完成这一操作之前,客户进程不应当去取这些数据。通常,信号量被用来实现对共享存储区的同步访问。
共享内存要用到一下几个函数:
key_t ftok(char *path,int id)
注意:这个函数是获取一个键值,path要为一个具体存在的路径名,id要为一个宏
例如:
#define number 255
key=ftok("/dev/null",number)
int shmget(key_ key,size_t size,int flag)
这个函数是获取一个共享存储标识符
int shmctl(int shmid,int cmd,struct shmid_ds *buf)
这个函数可对共享存储段执行多种操作
cmd有三种值:
IPC_STAT 取此段的shmid_ds结构,并将它存放在由buf值向的结构中
IPC_SET  按buf指向结构中的值设置与此段相关结构中的三个字段shm_perm.uid、shm_perm.gid、shm_perm.mode
IPC_RMID 从系统中删除该共享存储段
void *shmat(int shmid,void *addr,int flag)
创建一个共享存储段,若成功就返回指向共享存储段的指针,失败返回-1.
addr通常为0,表示由系统分配共享存储段
flag通常为0,表示以读写方式访问共享存储段
int shmdt(void *addr)
当对共享存储段的操作结束时,则调用shmdt脱接该段。注意,这并不是从系统中删除其标识符以及其数据结构。该标识符任然存在,直至某个进程调用shmctl特地删除它。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SIZE 1024
#define exit_err(str) do{perror(str);exit(1);}while(0);
#define uint32 unsigned long
int main()
{
int shmid;
char *shmptr;
key_t key;
pid_t pid;
if((pid = fork()) < 0)
exit_err("fork error");
 if(pid == 0)
{
sleep(2);
if((key = ftok("/dev/null", O_RDWR)) < 0)
exit_err("ftok error");
if((shmid = shmget(key, SIZE, 0600|IPC_CREAT)) < 0)
{
    printf("1\n");
    exit_err("shmget error");
}
if((shmptr = (char*)shmat(shmid, 0, 0)) == (void*)-1)
   exit_err("shmat error");
printf("child_pid is %d,share memory from %lx to %lx, content:%s\n",getpid(), (uint32)shmptr, (uint32)(shmptr + SIZE), shmptr);
printf("child sleep 2s\n");
sleep(2);
if((shmctl(shmid, IPC_RMID, 0) < 0))
     exit_err("shmctl error");
exit(0);
}
else
{
if((key = ftok("/dev/null", O_RDWR)) < 0)
    exit_err("ftok error");   
if((shmid = shmget(key, SIZE, 0600|IPC_CREAT|IPC_EXCL)) < 0)
  exit_err("shmget error");
if((shmptr = (char*)shmat(shmid, 0, 0)) == (void*)-1)
  exit_err("shmat error");
memcpy(shmptr, "hello world", sizeof("hello world"));
printf("parent:pid is %d,share memory from %lx to %lx, content:%s\n",getpid(),(uint32)shmptr, (uint32)(shmptr + SIZE
), shmptr);
printf("parent sleep 2s\n");
sleep(2);
}
waitpid(pid,NULL,0);
exit(0);
}
上面的是在一个程序中实现两个进程通过共享内存通信,下面的是分成两个程序实现两个进程的通信
 
//send.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define number 255
int main()
{
int shmid;
char *p_addr;
void *buf;
key_t key;
if((key=ftok("/dev/null",O_RDWR))!=0)
printf("%lx\n",key);
if((shmid=shmget(key,1024,IPC_CREAT|0666))==-1)
{
perror("shmget error");
exit(1);
}
if((p_addr=(char *)shmat(shmid,0,0))==(char *)-1)
{
perror("shmat error");
exit(1);
}
memset(p_addr,'\0',1024);
strncpy(p_addr,"test memery communicate",1024);
return 0;
}
//recieve.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define number 255
int main()
{
int shmid;
char *c_addr;
void *buf;
key_t  key;
if((key=ftok("/dev/null",O_RDWR))==-0)
printf("%lx",key);
if((shmid=shmget(key,1024,0666))==-1)
{
perror("shmget error");
exit(1);
}
if((c_addr=(char *)shmat(shmid,0,0))==(char *)-1)
{
perror("shmat error");
exit(1);
}
printf("client get str = %s\n",c_addr);
shmctl(shmid,IPC_RMID,0);
return 0;
}
阅读(2145) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~