共享内存System V

来源:互联网 发布:张大奕的淘宝店成功 编辑:程序博客网 时间:2024/04/28 13:44

system V 共享内存区
    对于每个共享内存区,内核维护如下的信息结构: <sys/shm.h>
/* Obsolete, used only for backwards compatibility and libc5 compiles */
struct shmid_ds {
    struct ipc_perm        shm_perm;    /* operation perms */
    int            shm_segsz;    /* size of segment (bytes) */
    __kernel_time_t        shm_atime;    /* last attach time */
    __kernel_time_t        shm_dtime;    /* last detach time */
    __kernel_time_t        shm_ctime;    /* last change time */
    __kernel_ipc_pid_t    shm_cpid;    /* pid of creator */
    __kernel_ipc_pid_t    shm_lpid;    /* pid of last operator */
    unsigned short        shm_nattch;    /* no. of current attaches */
    unsigned short         shm_unused;    /* compatibility */
    void             *shm_unused2;    /* ditto - used by DIPC */
    void            *shm_unused3;    /* unused */
};   


    struct shmid_ds
    {
        struct ipc_perm shm_perm; //权限
        size_t shm_segsz ;  //共享内存区的大小
        pid_t shm_lpid; //pid of last operation
        pid_t shm_cpid; //creator pid
        
        shmatt_t shm_nattch;  //number of current attaches
        
        time_t shm_atime;   //last attach time
        time_t shm_dtime;    //last dettach time
        time_t shm_ctime;   //last change time of this structure
    };
    
    
共享内存操作API:
0. ftok申请一个system v ipc的key

1. shmget: 创建或打开一个system v共享内存区

2. shmat:  把共享内存区映射到进程地址空间

3. shmdt: 把共享内在区解映射

4. shmctl: 对共享内存区进行控制操作


1. shmget: 用来创建或打开一个共享内存区

NAME
       shmget - allocates a System V shared memory segment

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

       int shmget(key_t key, size_t size, int shmflg);
            key:system v ipc对象的key
            size: 以字节为单位指定内存区的大小。
                当实际操作为创建一个新的内存区时,
                必须指定一个不为0的size值。如果实际操作
                为访问一个已经存在的共享内存区,那么
                size应为0.  共享内存区的大小为PAGE_SIZE(4k)的
                整数倍。
            shmflg: 标志位:
                    (1) 创建 IPC_CREAT |权限位
                    (2) 打开  0
        返回值:
            成功返回打开的共享内存区的ID(不是文件描述符)
            失败返回-1,  errno被设置
           
2. shmat
    NAME
       shmat, shmdt - System V shared memory operations

SYNOPSIS
       #include <sys/types.h>
       #include <sys/shm.h>

        shmat用来把共享内存区映射到进程自己的地址空间。
       void *shmat(int shmid, const void *shmaddr, int shmflg);
               shmid: 要映射的共享内存区
               shmaddr:指定映射到进程地址空间具体哪个地址。
                       如为NULL(一般也为NULL),则让操作系统自动
                       确定映射地址。
               shmflg:     映射标志
                       (1) SHM_RDONLY 只读
                       (2) 0  可读可写
               返回值:
                   成功返回映射共享内存区的首地址,
                   失败返回NULL


       
3
       int shmdt(const void *shmaddr);
shmdt用来解映射的
       int shmdt(const void *shmaddr);

4.

NAME
       shmctl - System V shared memory control

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

        shmctl用来对共享内存区进行控制操作的
       int shmctl(int shmid, int cmd, struct shmid_ds *buf);
           shmid: 共享内存区的ID,表示要对哪个共享内存区进行控制操作
           cmd: 操作命令。常用有三个:
               IPC_RMID: 删除共享内存区.此时,第三个参数为NULL
               IPC_STAT:获取共享内存区的属性信息。
                       获取到的属性信息保存在第三个参数
                           buf指向的结构体当中。
               IPC_SET: 设置共享内存区的属性信息。
                       通过第三个参数buf指向的结构体来改变。
                       shmid_ds结构以下三个成员,可以被你改变:
                           shm_perm. uid,  shm_perm.gid, shm_perm.mode.
           buf:

        返回值:
             成功返回0,
             失败返回-1, errno被设置




DEMO:

#include <stdio.h>#include <sys/types.h>#include <sys/ipc.h>#include <errno.h>#include <sys/shm.h>#include <string.h>#define PATH_NAME "/home/klein"#define PROJ_ID 34int main(int argc,char** argv){//1,obtain a key//key_t ftok(const char *pathname, int proj_id);key_t key = ftok(PATH_NAME,PROJ_ID);if(key == -1){perror("ftok error");return -1;}//2.get shared memory//int shmget(key_t key, size_t size, int shmflg);int shm_id = shmget(key,3,IPC_CREAT | 0666);//obtain a pagesize (4k)if(shm_id == -1){perror("shmget error");return -1;}//3. void *shmat(int shmid, const void *shmaddr, int shmflg);char *p = shmat(shm_id,NULL,0);/*If  shmaddr  is NULL, the system chooses a suitable (unused) address at       which to attach the segment.*/strcpy(p,"hello,shared memory content.");shmdt(p);return 0;}



#include <stdio.h>#include <sys/types.h>#include <sys/ipc.h>#include <errno.h>#include <sys/shm.h>#include <string.h>#define PATH_NAME "/home/klein"#define PROJ_ID 34int main(int argc,char** argv){//1,obtain a key//key_t ftok(const char *pathname, int proj_id);key_t key = ftok(PATH_NAME,PROJ_ID);if(key == -1){perror("ftok error");return -1;}//2.get shared memory//int shmget(key_t key, size_t size, int shmflg);int shm_id = shmget(key,3,IPC_CREAT | 0666);//obtain a pagesize (4k)if(shm_id == -1){perror("shmget error");return -1;}//3. void *shmat(int shmid, const void *shmaddr, int shmflg);char *p = shmat(shm_id,NULL,0);/*If  shmaddr  is NULL, the system chooses a suitable (unused) address at       which to attach the segment.*///strcpy(p,"hello,shared memory content.");printf("%s\n",p);shmdt(p);return 0;}






0 0