众所周知,进程间通讯有三种方式,信号量、消息队列和共享内存。不过信号量我的感受不像通讯,其实就是一个锁的东西。数组
共享内存,无非就是在内存段开辟一段小内存,返回地址,供以多个进程来使用,有的进程来这里存数据,有的进程来取数据。函数
要使用一块共享内存,进程必须首先分配它。随后须要访问这个共享内存块的每个进程都必须将这个共享内存绑定到本身的地址空间中。当完成通讯以后,全部进程都将脱离共享内存,而且由一个进程释放该共享内存块。全部共享内存块的大小都必须是系统页面大小的整数倍。(4K*n)
ui
1.API:spa
共享内存函数由shmget、shmat、shmdt、shmctl四个函数组成。按步骤以下:
指针
1shmget: int shmget(key_t key, size_t size, int shmflg) 获得一个共享内存标识符或建立一个共享内存对象并返回共享内存标识符
code
key
|
0(IPC_PRIVATE):会创建新共享内存对象
|
大于0的32位整数:视参数shmflg来肯定操做。一般要求此值来源于ftok返回的IPC键值
|
|
size
|
大于0的整数:新建的共享内存大小,以字节为单位
|
0:只获取共享内存时指定为0
|
|
shmflg
|
0:取共享内存标识符,若不存在则函数会报错
|
IPC_CREAT:当shmflg&IPC_CREAT为真时,若是内核中不存在键值与key相等的共享内存,则新建一个共享内存;若是存在这样的共享内存,返回此共享内存的标识符
|
|
IPC_CREAT|IPC_EXCL:若是内核中不存在键值与key相等的共享内存,则新建一个消息队列;若是存在这样的共享内存则报错
|
2shmat :把共享内存区对象映射到调用进程的地址空间htm
void *shmat(int shmid, const void *shmaddr, int shmflg)
对象
shmid
|
共享内存标识符
|
shmaddr
|
指定共享内存出如今进程内存地址的什么位置,直接指定为NULL让内核本身决定一个合适的地址位置
|
shmflg
|
SHM_RDONLY:为只读模式,其余为读写模式
|
3 管控共享内存 int shmctl(int shmid, int cmd, struct shmid_ds *buf)队列
shmid
|
共享内存标识符
|
cmd
|
IPC_STAT:获得共享内存的状态,把共享内存的shmid_ds结构复制到buf中
|
IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内
|
|
IPC_RMID:删除这片共享内存
|
|
buf
|
共享内存管理结构体。具体说明参见共享内存内核结构定义部分
|
4 断开共享内存链接 int shmdt(const void *shmaddr) //shmaddr:链接的共享内存的起始地址进程
2.小例子和解释:
发送方.c进程申请一段共享内存,把一个结构体放入里面,接收方.c进程读取这段内存,读出内容。
SENDER.C
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
struct personinfo{ //要存放的结构体
char name[10];
int number;
float scores;
};
typedef struct personinfo * player; //声明结构体指针
int main(void){
int shmid;
shmid=shmget(IPC_PRIVATE,4096,0666); //申请共享内存,大小4K,有rwxrwxrwx权限
if(shmid==-1) // shmid就是共享内存的标识
exit(1);
printf("shmid is %d\n",shmid);
player wade; //建立一个指针对象
wade=shmat(shmid,NULL,0);// shmat(shmid,NULL,0)就是把shmid标识的共享内存的地址链接到本进程,这里直接给到结构体指针,就是把结构体指针指向这段内存;
strcpy(wade->name,"dwyane_wade");
wade->number=3;
wade->scores=20.13;
if(shmdt(wade)<0)//解除连接
exit(1);
return 0;
}
RSVER.C
#include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> struct personinfo{ char name[10]; int number; float scores; }; typedef struct personinfo * player; int main(int argc,char *argv[]){ int shmid; shmid=atoi(argv[1]);// 从输入端把SENDER.C获得的shmid输入 player lee; if((lee=shmat(shmid,NULL,0))==NULL) //把指针指向内存这里 exit(1); printf("name %s\n",lee->name); //读取数据 printf("number %d\n",lee->number); printf("scores %f\n",lee->scores); }
运行结果应该是 dwyane_wade\n 3\n 20.129999\n