API介绍:
1. int shmget(key_t key, size_t size, int shmflg);
函数描述:创建或者获取共享内存的描述符;
第一个参数是ftok返回的key,
第二个参数是共享内存的大小,当是获取描述符时,写0
第三个参数是标志位,如果创建共享内存 IPC_CREAT|0666 如果获取共享内存的话写 0;
和其他的IPC 函数一样,返回值是共享内存的描述符;
2. void *shmat(int shmid, const void *shmaddr, int shmflg);
函数描述:挂接共享内存,并返回共享内存的首地址。
第一个参数是共享内存的描述符;
第二个参数是共享内存要挂接的地址,可以自己分配内存地址;如果写0,表示有操作系统自己分配,
第三个参数共享内存的属性,SHM_RDONLY 表示创建的共享内存是只读的,
0表示默认属性,即可读可写,
返回值是共享内存的首地址;
3.int shmdt(const void *shmaddr);
函数描述:分离共享内存,表示本进程不在占用共享内存的资源。
参数是共享内存的首地址。
4. int shmctl(int shmid, int cmd, struct shmid_ds *buf);
函数描述:根据不同的命令操作共享内存,
第一个参数是共享内存的描述符;
第二个参数是命令,常用的是IPC_STAT,IPC_RMID
第三个参数是一个结构体指针,当获取共享内存的信息是会用到这个结构体;
如:命令是IPC_STAT时,会将获取到的共享内存信息放入 结构体buf中,可以把它当成是一个输出参数。
如果是 IPC_RMID 则第三个参数就设为0或者NULL 代表删除共享内存;
struct shmid_ds {
struct ipc_perm shm_perm; /* 这个数一个结构体,署名了属主关系和共享内存的权限*/
size_t shm_segsz; /* 共享内存的大小,单位:字节*/
time_t shm_atime; /* 最后一次的挂接时间*/
time_t shm_dtime; /* 最后一次的分离时间*/
time_t shm_ctime; /* 最后一次的更改时间*/
pid_t shm_cpid; /* 创建者的PID*/
pid_t shm_lpid; /* 进行最后一次挂接或者分离操作的PID*/
shmatt_t shm_nattch; /* 共享内存的挂接数量*/
...
使用共享内存:
1. int shmget(key_t key, size_t size, int shmflg);
函数描述:创建或者获取共享内存的描述符;
第一个参数是ftok返回的key,
第二个参数是共享内存的大小,当是获取描述符时,写0
第三个参数是标志位,如果创建共享内存 IPC_CREAT|0666 如果获取共享内存的话写 0;
和其他的IPC 函数一样,返回值是共享内存的描述符;
2. void *shmat(int shmid, const void *shmaddr, int shmflg);
函数描述:挂接共享内存,并返回共享内存的首地址。
第一个参数是共享内存的描述符;
第二个参数是共享内存要挂接的地址,可以自己分配内存地址;如果写0,表示有操作系统自己分配,
第三个参数共享内存的属性,SHM_RDONLY 表示创建的共享内存是只读的,
0表示默认属性,即可读可写,
返回值是共享内存的首地址;
3.int shmdt(const void *shmaddr);
函数描述:分离共享内存,表示本进程不在占用共享内存的资源。
参数是共享内存的首地址。
4. int shmctl(int shmid, int cmd, struct shmid_ds *buf);
函数描述:根据不同的命令操作共享内存,
第一个参数是共享内存的描述符;
第二个参数是命令,常用的是IPC_STAT,IPC_RMID
第三个参数是一个结构体指针,当获取共享内存的信息是会用到这个结构体;
如:命令是IPC_STAT时,会将获取到的共享内存信息放入 结构体buf中,可以把它当成是一个输出参数。
如果是 IPC_RMID 则第三个参数就设为0或者NULL 代表删除共享内存;
struct shmid_ds {
struct ipc_perm shm_perm; /* 这个数一个结构体,署名了属主关系和共享内存的权限*/
size_t shm_segsz; /* 共享内存的大小,单位:字节*/
time_t shm_atime; /* 最后一次的挂接时间*/
time_t shm_dtime; /* 最后一次的分离时间*/
time_t shm_ctime; /* 最后一次的更改时间*/
pid_t shm_cpid; /* 创建者的PID*/
pid_t shm_lpid; /* 进行最后一次挂接或者分离操作的PID*/
shmatt_t shm_nattch; /* 共享内存的挂接数量*/
...
};
创建共享内存:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <string.h>
void err(char *p)
{
perror(p);
exit(-1);
}
int main()
{
key_t key = ftok(".",123);
if(key == -1) err("ftok");
int shmid = shmget(key,1024,IPC_CREAT);
if(shmid == -1) err("shmget");
char *p = shmat(shmid,0,0);
strcpy(p,"I'm coming !");
}
使用共享内存:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <time.h>
void err(char *p)
{
perror(p);
exit(-1);
}
void get_time(const time_t *tp,char *rp)
{
struct tm *st=localtime(tp);
sprintf(rp,"%d-%d-%d %02d:%02d:%02d",st->tm_year+1900,st->tm_mon+1,st->tm_mday,
st->tm_hour,st->tm_min,st->tm_sec);
}
int main()
{
key_t key = ftok(".",123);
if(key == -1) err("ftok");
int shmid = shmget(key,0,0);
char *p=shmat(shmid,0,0);
printf("p = %s \n",p);//打印共享内存中的信息
struct shmid_ds sds;
shmctl(shmid,IPC_STAT,&sds); //获取共享内存的状态
shmdt(p);
char s_a[20],s_d[20];
get_time(&sds.shm_atime,s_a); //将时间整数转换成自定义格式的时间字符串
get_time(&sds.shm_dtime,s_d);
printf("sds.shm_segsz = %d\n",sds.shm_segsz);
printf("sds.shm_atime = %s\n",s_a);
printf("sds.shm_dtime = %s\n",s_d);
printf("sds.shm_cpid = %d\n",sds.shm_cpid);
printf("sds.shm_lpid = %d\n",sds.shm_lpid);
printf("sds.shm_nattch = %d\n",sds.shm_nattch);
}
运行结果:
创建共享内存的程序是set,使用共享内存的程序是get;