Linux进程通信之共享内存

  • 这里简介一下共享内存的编程的模型,其它细节以后有时间再补充
  1. 创建共享内存,得到一个ID(函数shmget)
  2. 把ID映射成虚拟地址/挂载 (函数shmat)
  3. 使用虚拟地址访问内核共享内存,可以使用任何内存函数函数与运算符号
  4. 卸载虚拟地址 (函数shmdt)
  5. 删除共享内存 ,函数shctl(修改,获取共享内存的属性)
  • 这里看下几个函数

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

       int shmget(key_t key, size_t size, int shmflg);
  • 对于创建共享内存的进程来讲,这个函数返回共享内存的Id,而对于接收方进程来讲,它通过这个函数来获取共享内存的Id,而如何获取到相同的Id则是由第一个参数key来决定的,大概可以理解为,创建共享内存的时候,把传入的key和内存的Id关联起来,等到接收方传入相同的key的时候,便会返回相同的Id.而保证key相同的办法则可以通过ftok函数利用相同的目录来获取,这里不作详述。只需要知道,传入相同的key就可以获取共享内存的Id即可。

  • 第二个参数size则是共享内存的大小

  • 第三个参数需要注意一下,一般来讲,创建者进程,一般传入IPC_CREAT|IPC_EXCL|权限,而作为接收方,传入0即可,其他细节请查看手册。

  • 调用成功则返回Id,否则返回-1

  • 对接收方进程而言,最后一个参数传入0即可。

接着调用shmat来得到共享内存,进行读写。shmdt来进行卸载

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

       void *shmat(int shmid, const void *shmaddr, int shmflg);

       int shmdt(const void *shmaddr)

最后是shmctl

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

       int shmctl(int shmid, int cmd, struct shmid_ds *buf);
  • 第一个参数是由shmget返回的Id

  • 第二个参数cmd 则是选择工作的方式

IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中
IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内
IPC_RMID:删除这片共享内存

一般我们用来删除Id的话,传入IPC_RMID即可,接收方不需要删除共享内存

举个栗子

shmA.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <signal.h>


key_t key;
int shmId;
int* p;
int i=0;
void handle(int s){
    if(s==SIGINT){
        shmdt(p);
        shmctl(shmId,IPC_RMID,0);
        exit(0);
    }

}

int main(){

    signal(SIGINT,handle);
    //1. create shared memory
    //
    key=ftok(".",255);
    if(key==-1)printf("ftok error,%m\n"),exit(-1);
    shmId=shmget(key,4,IPC_CREAT|IPC_EXCL|0666);
    if(shmId==-1)printf("shmget error,%m\n"),exit(-1);
    //2. attach shared memory
    p=shmat(shmId,0,0);
    if(p==(int*)-1)printf("shmat error,%m\n"),exit(-1);
    //3. use virtual address operate data
    while(1){
        *p=i++;;
        sleep(1);
    }

    //4. deattach shared memory
    //5. control(delete shared memory)

    return 0;
}

shmB.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <signal.h>


    key_t key;
    int shmId;

    int *p;
void handle(int s){
    if(s==SIGINT){
        shmdt(p);
        exit(0);
    }
}


int main(){
    signal(SIGINT,handle);
    //1. create shared memory
    key=ftok(".",255);
    if(key==-1)printf("ftok error,%m\n"),exit(-1);
    shmId=shmget(key,4,0);
    if(shmId==-1)printf("shmget error,%m\n"),exit(-1);
    //2. attach shared memory
    p=shmat(shmId,0,0);
    if(p==(int*)-1)printf("shmat error,%m\n"),exit(-1);
    //3. use virtual address operate data
    while(1){
        sleep(1);
        printf("num=%d\n",*p);
    }

    //4. deattach shared memory
    shmdt(p);
    //5. control(delete shared memory)
    //

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值