共享内存是允许多个进程共享内存;
共享内存结构
struct shmid_ds
{
struc ipc_perm shm_perm; //指向该内存指针
int shm_segsz; //共享内存的大小
ushort shm_lkcnt; //共享内存被锁定的时间
pid_t shm_cpid; //最近调用shompde进程的进程号
pid_t shm_lpid; //创建该共享内存进程的进程号
ulong shm_nattach; //当前把该内存段附加到地址空间的进程数
time_t shm_atime; //最新附加操作时间
time_t shm_dtime; //最新分离时间
time_t shm_ctime; //最新改变时间
}
需要的库
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
共享内存创建与打开
int shmget(key_t key, int size, int flag);
key关键字;
size内存大小
flag操作类型
当key = IPC_PRIVATE; flag任何值时,创建新内存。
当key != IPC_PRIVATE; flag = IPC_CREATE 时,打开已有共享内存;否则,创建新内存。
当key != IPC_PRIVATE; flag = IPC_CREATE | IPC_EXCL时,打开已有共享内存,否则失败;
共享内存操作
void* shmat(int shmid ,void *addr, int flag);
当addr= 0; flag 任何值 时,将共享内存附加到第一块有效内存区域。
当addr != 0; flag !=SHM_RND 时,将共享内存附加到addr指向内存地址。
当addr != 0; flag !=SHM_RND 时,将共享内存附加到addr-(addr%SHMLBA)指向内存地址。
共享内存操作
int shmctl(int shmid, int cmd, shmid_ds *buf);
cmd的取值与对应操作
SHM_LOCK 由超级用户上锁
IPC_RMID 删除共享内存
IPC_SET 按参数buf指向结构中的值设置该共享内存对应的shmid_ds结构
IPC_STAT 取出shmid_ds结构,并保存到buf所指向的缓冲区
SHM_UNLOCK 由超级用户解锁
举例:
在服务端创建共享内存,然后在客户端读取
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
int main()
{
int shmid;
char c;
char *shmptr, *s;
if((shmid = shmget(1234,256,IPC_CREAT|0666))<0)
{
printf("shmget failed\n");
exit(1);
}
if((shmptr = shmat(shmid, 0 ,0))==-1)
{
shmctl(shmid,IPC_RMID, shmptr);
printf("shmat failed\n");
exit(2);
}
s = shmptr;
for(c = 'a'; c<= 'z';c++)
*s++ = c;
*s = NULL;
while(*shmptr!='*')
sleep(1);
shmctl(shmid, IPC_RMID, shmptr);
return 0;
}
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
int main()
{
int shmid;
char c;
char *shmptr,*s;
if((shmid = shmget(1234,256,0666)) < 0)
{
printf("shmget failed\n");
exit(1);
}
if((shmptr = shmat(shmid, 0, 0))<0)
{
shmctl(shmid, IPC_RMID, shmptr);
printf("shmptr failed\n");
exit(2);
}
for(s = shmptr; *s!=NULL; s++)
{
*s -= 32;
putchar(*s);
};
printf("\n");
*shmptr='*';
return 0;
}