您的位置:首页 > 运维架构 > Linux

linux进程通信-共享内存

2016-11-02 23:18 316 查看
共享内存
  1. 共享内存的实现原理
创建共享内存、打开共享内存
映射共享内存
分享共享内存
控制共享内存
(1)shmget
函数的作用:在内核中创建共享内存
函数的原型:int shmget(key_tkey,int size,int shmflag);
函数的参数:key:键值;
size:创建的内存大小;
shmflag:标志(同open函数的权限位)
返回值:成功:共享内存标识符;
               出错-1
头文件:#include <sys/ipc.h>
                #include <sys/shm.h>
(2)shmat
函数的作用:映射共享内存,映射到各自的内存空间
函数的原型:void * shmat(intshmid,const void *shmaddr,int shmflag);
函数的参数:shmid:内存标识符
shmaddr:映射共享内存到本进程指定地址,若为NULL,则由内核自动分配
shmflag:SHM_RDONLY:共享内存只读
                0:共享内存可读写
返回值:成功:被映射的段地址;
                出错-1
头文件:#include <sys/ipc.h>
                #include <sys/shm.h>
(3)shmdt
函数的作用:撤销共享内存的映射
函数的原型:int shmat(constvoid *shmaddr);
函数的参数:shmaddr:被映射的共享内存的地址
返回值:成功0;
                出错-1
头文件:#include <sys/ipc.h>
                #include <sys/shm.h>
 
  2.共享内没有血缘关系之间如何通信?通过设置相同的键值。(程序如下)
shm1.c
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "shm_com.h"

int main()
{
int running = 1;
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
int shmid;

//创建共享内存
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT);

if(shmid == -1)
{
fprintf(stderr, "shmget failed\n");
exit(EXIT_FAILURE);
}

//映射共享内存
shared_memory = shmat(shmid, (void *)0, 0);

if(shared_memory == (void *)-1)
{
fprintf(stderr, "shmat failed\n");
exit(EXIT_FAILURE);
}

printf("Memory attached at %X\n", (int)shared_memory);

//让结构体指针指向这块共享内存
shared_stuff = (struct shared_use_st *)shared_memory;

//控制读写顺序
shared_stuff->written_by_you = 0;

//循环的从共享内存中读数据,直到读到end为止
while(running)
{
if(shared_stuff->written_by_you)
{
printf("You wrote:%S\n", shared_stuff->some_text);
sleep(1);//读进程一秒,同时会导致写进程睡一秒,这样做到读了之后再写
shared_stuff->written_by_you = 0;

if(strncmp(shared_stuff->some_text, "end", 3) == 0)
{
running = 0;//结束循环
}
}
}

//删除共享内存
if(shmdt(shared_memory) == -1)
{
fprintf(stderr, "shmdt failed!\n");
exit(EXIT_FAILURE);
}

exit(EXIT_SUCCESS);

}
shm2.c
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "shm_com.h"

int main()
{
int running = 1;
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
char buffer[BUFSIZ];
int shmid;

//创建共享内存
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT);

if(shmid == -1)
{
fprintf(stderr, "shmget failed\n");
exit(EXIT_FAILURE);
}

//映射共享内存
shared_memory = shmat(shmid, (void *)0, 0);

if(shared_memory == (void *)-1)
{
fprintf(stderr, "shmat failed\n");
exit(EXIT_FAILURE);
}

printf("Memory attached at %X\n", (int)shared_memory);

//循环的向共享内存中写数据,直到写入的为end为止
shared_stuff = (struct shared_use_st *)shared_memory;

while(running)
{
while(shared_stuff->written_by_you == 1)
{
sleep(1);//等到读进程完之后再写
printf("Waiting for client...\n");
}

printf("Enter some text:");
fgets(buffer, BUFSIZ, stdin);
strncpy(shared_stuff->some_text, buffer, TEXT_SZ);
shared_stuff->written_by_you = 1;

if(strncmp(buffer, "end", 3) == 0)
{
running = 0;//结束循环
}

}

//删除共享内存
if(shmdt(shared_memory) == -1)
{
fprintf(stderr, "shmdt failed!\n");
exit(EXIT_FAILURE);
}

exit(EXIT_SUCCESS);

}
运行结果如下:





shmem.c
#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
/* 共享内存 */

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);
}

/* 创建共享内存 */
if((shmid=shmget(IPC_PRIVATE,1024,PERM))==-1)
{
fprintf(stderr,"Create Share Memory Error:%s\n\a",strerror(errno));
exit(1);
}

/* 创建子进程 */
if(fork()) // 父进程写
{
p_addr=shmat(shmid,0,0);
memset(p_addr,'\0',1024);
strncpy(p_addr,argv[1],1024);
wait(NULL); // 释放资源,不关心终止状态
exit(0);
}
else // 子进程读
{
sleep(1); // 暂停1秒
c_addr=shmat(shmid,0,0);
printf("Client get %s\n",c_addr);
exit(0);
}
}
运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: