码迷,mamicode.com
首页 > 其他好文 > 详细

System V 共享内存

时间:2015-05-24 08:55:18      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:共享内存   ipc   进程间通信   linux   

一.共享内存数据结构


对于每个共享内存区,内核维护如下信息结构,定义在<sys/shm.h>, 在ubuntu中路径:/usr/include/linux/shm.h


技术分享


二. System V共享内存函数:

#include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key, size_t size, int shmflg);    
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
;


(1)
功能:用来创建共享内存
原型 int shmget(key_t key, size_t size,
int shmflg);

参数:
     key: 这个共享内存段名字

     size: 共享内存大小

     shmflg: 由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的


返回值:    成功返回一个非负整数,即该共享内存段的标识码;
        失败返回-1

(2)
功能:将共享内存段连接到进程地址空间
原型
void *shmat(int shmid, const void *shmaddr, int shmflg);
参数
    shmid:   共享内存标识
    shmaddr: 指定连接的地址
    shmflg:  它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一个指针,指向共享内存第一个字节;失败返回-1

  shmaddr 为NULL,内核自动选择一个地址
  shmaddr 不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址。
  shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。
            公式:shmaddr - (shmaddr % SHMLBA)    # SHMLBA为4096
 shmflg=SHM_RDONLY,表示连接操作用来只读共享内存


(3)
功能:将共享内存段与当前进程脱离
原型 int shmdt(const void *shmaddr);
参数
    shmaddr: 由shmat所返回的指针
    返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段

(4)
功能:用于控制共享内存
原型 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数
    shmid: 由shmget返回的共享内存标识码
    cmd:   将要采取的动作(有三个可取值)
    buf:    指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1

cmd 的取值如下,与消息队列类似:
    IPC_STAT 把shmid_ds结构中的数据设置为共享内存的当前关联值
    IPC_SET   在进程有足够权限的前提下,把共享内存的当前关联值设置为shmid_ds数据结构中给出的值

    IPC_RMID 删除共享内存段

shmwrite.c

#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/types.h>
#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/mman.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<string.h>

#define ERR_EXIT(m)     do {         perror(m);         exit(EXIT_FAILURE);     } while(0)

typedef struct stu
{
    char name[32];
    int age;
} STU;

int main(int argc, char *argv[])
{
    int shmid;
    shmid = shmget(1234,sizeof(STU),IPC_CREAT | 0666); //用来创建共享内存
    if(shmid == -1)
    	ERR_EXIT("shmget err");
    STU *p;
    p = shmat(shmid,NULL,0);//将共享内存段连接到进程地址空间
    if(p == (void*)-1)  //error (void *) -1 is returned
    	ERR_EXIT("shmat err");
    strcpy(p->name,"list");
    p->age = 20;
    while(1)  // 等待,接收内存中有quit字符串时,代表读取完成
    {
    	if(memcmp(p,"quit",4) == 0)// 需要注意的是,这里比较的是内存
    		break;
    }
    //sleep(10);
    shmdt(p);//将共享内存段与当前进程脱离
    shmctl(shmid,IPC_RMID,NULL);
    return 0;
}


shmread.c

#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/types.h>
#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/mman.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<string.h>

#define ERR_EXIT(m)     do {         perror(m);         exit(EXIT_FAILURE);     } while(0)

typedef struct stu
{
    char name[32];
    int age;
} STU;

int main(int argc, char *argv[])
{
    int shmid;
    shmid = shmget(1234,0,0); //用来创建共享内存
    if(shmid == -1)
    	ERR_EXIT("shmget err");
    STU *p;
    p = shmat(shmid,NULL,0);//将共享内存段连接到进程地址空间
    if(p == (void*)-1)  //error (void *) -1 is returned
    	ERR_EXIT("shmat err");
   
   	printf("name=%s  age=%d\n",p->name,p->age);
    
    memcpy(p,"quit",4);  // 读取完数据后,向内存中写入4个字节的数据,代表读取完成
    shmdt(p);//将共享内存段与当前进程脱离
    return 0;
}



System V 共享内存

标签:共享内存   ipc   进程间通信   linux   

原文地址:http://blog.csdn.net/u014304293/article/details/45939015

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!