linux-c: ipc_共享内存
简介共享内存是进程间通讯的一种机制,在数据量较大时,比较合适。每个共享内存对象都有一个shmid_ds结构体与之对应,代表共享内存的一些信息。因为shm是SYSV子系统的一种机制,所以有SYSV的一些特性,1、引用标识符:用来访问对象2、键:定位引用标识符3、ipc_perm结构:记录一些状态信息要引入的文件 #i nclude #i nclude #i nclude 创建共享内存与打
简介
共享内存是进程间通讯的一种机制,在数据量较大时,比较合适。每个共享内存对象都有一个
shmid_ds结构体与之对应,代表共享内存的一些信息。
因为shm是SYSV子系统的一种机制,所以有SYSV的一些特性,
1、引用标识符:用来访问对象
2、键:定位引用标识符
3、ipc_perm结构:记录一些状态信息
要引入的文件
#i nclude <sys/types.h>
#i nclude <sys/ipc.h>
#i nclude <sys/shm.h>
创建共享内存与打开
int shmget(key_t key, int size, int flag);
int newshm()
{
int shmid;
shmid = shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE); //创建
//shmid = shmget(88, SHM_SIZE, SHM_MODE|IPC_CREAT);//如果88存在-打开,如果88不存在-创建
//shmid = shmget(88, SHM_SIZE, SHM_MODE|IPC_CREAT|IPC_EXCL);//如果88存在-失败,如果88不存在-创建
//shmid = shmget(0x90, SHM_SIZE, SHM_MODE|IPC_CREAT|IPC_EXCL);//同上,但key用16进制
if(shmid == -1)
printf("newshm error/n");
return shmid;
}
key为IPC_PRIVATE时代表创建,size为大小,此时flag不起作用
key不为IPC_PRIVATE时,如果flag有IPC_CREAT但没有IPC_EXCL时,如果key已经存在代表打开(size不起作用),否则代表创建
key不为IPC_PRIVATE时,如果flag有IPC_CREAT且有IPC_EXCL时,代表创建,如果key已经调用失败
成功返回引用标识符,失败返回-1
附加共享内存
void * shmat(int shmid, void *addr,int flag);
char * getshm(int shmid)
{
char *ptr;
ptr = shmat(shmid, 0, 0);
if(ptr == (void*) -1)
printf("getshm error/n");
return ptr;
}
调用方法按例子简单调用即可,更多参数说明可以查看网上资料,此时可以用strcpy向ptr中写数据,即是写到共享内存中。
分离共享内存
int shmdt(void *addr);
void dtshm(char * ptr)
{
int ret = shmdt(ptr);
if(ret<0)
printf("dtshm error/n");
}
将getshm取得的共享内存地址传入即可
控制共享内存
int shmctl(int shmid, int cmd, shmid_ds *buf);
具体做什么控制由cmd决定:
SHM_LOCK:上锁共享内存,只能由超级用户执行
IPC_RMID:删除共享内存
IPC_SET:设置共享内存,由buf决定
IPC_STAT:取得共享内存shmid_ds结构体
SHM_UNLOCK:解锁
删除:
void delshm(int shmid)
{
int ret;
ret = shmctl(shmid, IPC_RMID, 0);
if(ret<0)
printf("delshm error/n");
}
取shmid_ds结构体:
struct shmid_ds shmds;
void getstat(int shmid)
{
int ret;
ret = shmctl(shmid, IPC_STAT, &shmds);
if(-1 == ret)
printf("getstat error/n");
}
注意:删除与分离的区别
如果分离,本进程或其它进程还可以附加,并且分离后引用地址失效
如果删除,引用地址不立即失效,但不可以再附加。(进程结束或断开连接时才真正删除)
下面是一个测试程序:
#i nclude <sys/types.h>
#i nclude <sys/ipc.h>
#i nclude <sys/shm.h>
#define ARRAY_SIZE 400
#define BUF_SIZE 400
#define SHM_SIZE 1000
#define SHM_MODE SHM_W|SHM_R
int newshm();
char* getshm(int);
void getstat(int);
void delshm(int);
void printstat(struct shmid_ds *);
void dtshm(char*);
struct shmid_ds shmds;
int main()
{
int shmid;
char *shmptr;
shmid = newshm();
shmptr = getshm(shmid);
printf("%s/n", shmptr);
// getstat(shmid);
// printstat(&shmds);
//delshm(shmid);
//dtshm(shmptr);
//shmptr = getshm(shmid);
//strcpy(shmptr, "bbb");
//printf("%s/n", shmptr);
}
int newshm()
{
int shmid;
//shmid = shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE);
//shmid = shmget(88, SHM_SIZE, SHM_MODE|IPC_CREAT);
//shmid = shmget(88, SHM_SIZE, SHM_MODE|IPC_CREAT|IPC_EXCL);
shmid = shmget(0x90, SHM_SIZE, SHM_MODE|IPC_CREAT|IPC_EXCL);
if(shmid == -1)
printf("newshm error/n");
return shmid;
}
char * getshm(int shmid)
{
char *ptr;
ptr = shmat(shmid, 0, 0);
if(ptr == (void*) -1)
printf("getshm error/n");
return ptr;
}
void getstat(int shmid)
{
int ret;
ret = shmctl(shmid, IPC_STAT, &shmds);
if(-1 == ret)
printf("getstat error/n");
}
void dtshm(char * ptr)
{
int ret = shmdt(ptr);
if(ret<0)
printf("dtshm error/n");
}
void delshm(int shmid)
{
int ret;
ret = shmctl(shmid, IPC_RMID, 0);
if(ret<0)
printf("delshm error/n");
}
void printstat(struct shmid_ds *buf)
{
printf("struct ipc_perm:/n");
printf("uid=%d/n", buf->shm_perm.uid);
printf("gid=%d/n", buf->shm_perm.gid);
printf("cuid=%d/n", buf->shm_perm.cuid);
printf("cgid=%d/n", buf->shm_perm.cgid);
}
更多推荐
所有评论(0)