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

linux进程通信之共享内存

2017-02-17 21:54 489 查看
共享内存指 在多处理器的计算机系统中,可以被不同CPU访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,由于其他处理器也可能要存取,共享内存就需要立即更新,否则不同的处理器可能用到不同的数据。共享内存是
Unix,linux下的多进程之间的通信方法之一 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。



共享内存的不同进程可指向同一块内存地址,共享数据,减少访问cpu的时间,因此是进程间通信速度最快的。但是共享内存没有互斥,同步机制,对数据的访问可能不完整,数据读写存在相互烦扰的问题,可见共享内存这种通信方式也是有利有弊的。

函数接口

共享内存的实现主要有四个函数完成:获取共性内存shmget() ,建立连接shmat(),断开连接 shmdt(),销毁 shmctl()

头文件<sys/shm.h>

<sys/types.h>

<sys/ipc.h>

int shmget(key_t key, size_t size, int shmflg)

参数size 以页表为基本单位,是4k的整数倍(4096);

IPC_CREAT:当shmflg&IPC_CREAT为真时,如果内核中不存在键值与key相等的共享内存,则新建一个共享内存;如果存在这样的共享内存,返回此共享内存的标识符

void *shmat(int shmid, const void *shmaddr, int shmflg)

参数shmaddr指定共享内存出现在进程内存地址的什么位置

int shmdt(const void *shmaddr)

shmaddr:连接的共享内存的地址

int shmctl(int shmid, int cmd, struct shmid_ds *buf)

参数cmd为IPC_RMID销毁共享内存

buf共享内存管理结构体

实现代码

shm.h

#ifndef _SHM_

#define _SHM_

#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

#include<sys/shm.h>

#include<sys/types.h>

#include<sys/wait.h>

#include<sys/ipc.h>

#define PATH "."

#define PROJECT 0666

#define SIZE 4096*1

int get_shm();

char* at_shm(int shm_id);

int delete_shm(int shm_id);

int dt_shm(char* buf);

#endif

shm.c

#include"shm.h"
static int comm_shm(int flag)

{

int key=ftok(PATH,PROJECT);

if(key<0)

perror("ftok error");

int shm_id=shmget(key,SIZE,flag);

if(shm_id<0)

perror("shmget error");

return shm_id;

}

int get_shm()

{

int flag=IPC_CREAT|0666;

return comm_shm(flag);

}
char* at_shm(int shm_id) //连接信号

{

return (char*)shmat(shm_id,NULL,0);

}
int dt_shm(char* buf) //断开连接

{

return shmdt(buf);

}

int delete_shm(int shm_id) //销毁信号

{

return shmctl(shm_id,IPC_RMID,NULL);

}

main.c

#include"shm.h"

int main()

{

int shm_id=get_shm();

pid_t id=fork();

if(id<0)

{

printf("fork error");

return 1;

}

else if(id==0) //子进程

{

char* buf=at_shm(shm_id);

if(buf!=NULL)

{

int i=0;

while(i<4096)

{

buf[i]='a';

i++;

}

buf[4095]='\0';

}

dt_shm(buf);

}

else //父进程

{

char *buf = at_shm(shm_id); //建立连接

sleep(2);

printf("%s\n", buf);

dt_shm(buf);

waitpid(id, NULL, 0);

delete_shm(shm_id);

}

return 0;

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