linux共享存储通信实验,linux 进程间通信 共享存储

共享存储

共享存储允许两个或更多进程共享一个给定的存储段。因为数据部需要在客户进程和服务进程之间复制,所以这是最快的一种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;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值