进程间通信(IPC):共享内存(shared memory)和信号量(semaphore)


共享内存

🌔🌔🌔🌔🌔

  • 共享内存就是使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
  • 共享内存在进程空间的映射:
    在这里插入图片描述

使用共享内存通信的一般步骤

1、创建或者打开共享内存
2、进程A连接(映射)共享内存,写入数据
3、进程A断开
4、进程B连接(映射)共享内存,读取数据
5、进程B断开
6、释放共享内存

  • 示意图:在这里插入图片描述

创建共享内存

  • shmget函数:

    #include <sys/ipc.h>
    #include <sys/shm.h>
    int shmget(key_t key, size_t size,int shmflg);
    
    • 功能:创建或打开一块共享内存区。
    • 参数:
      • key:进程间通信键值,ftok() 的返回值。
      • size:该共享存储段的长度(字节)。
      • shmflg:标识函数的行为及共享内存的权限,其取值如下:
        • IPC_CREAT:如果不存在就创建
        • IPC_EXCL: 如果已经存在则返回失败
        • 位或权限位:共享内存位或权限位后可以设置共享内存的访问权限
    • 返回值: 成功返回共享内存标识符;失败返回-1。

共享内存的映射和解除映射

  • shmat函数:

    #include <sys/types.h>
    #include <sys/shm.h>
    
    void *shmat(int shmid, const void *shmaddr, int shmflg);
    
    • 功能: 将一个共享内存段映射到调用进程的数据段中

    • 参数:

      • shmid:共享内存标识符,shmget() 的返回值。
      • shmaddr:共享内存映射地址(若为 NULL 则由系统自动指定),推荐使用 NULL。
      • shmflg:共享内存段的访问权限和映射条件( 通常为 0 ),具体取值如下:
        • 0:共享内存具有可读可写权限。
        • SHM_RDONLY:只读。
        • SHM_RND:(shmaddr 非空时才有效)
    • 返回值: 成功返回共享内存段映射地址( 相当于这个指针就指向此共享内存 ) ;失败返回-1

  • shmdt函数:

    #include <sys/types.h>
    #include <sys/shm.h>
    
    int shmdt(const void *shmaddr);
    
    • 功能: 将共享内存和当前进程分离

    • 参数:

      • shmaddr:共享内存映射地址。
    • 返回值: 成功0 ;失败-1

共享内存操作函数

  • shmct函数:

    #include <sys/ipc.h>
    #include <sys/shm.h>
    
    int shmctl(int shmid, int cmd, struct shmid_ds *buf);
    
    • 功能: 共享内存属性的控制。
    • 参数:
      • shmid:共享内存标识符。

      • cmd:函数功能的控制,其取值如下:

        • IPC_RMID:删除
        • IPC_SET:设置 shmid_ds 参数,相当于把共享内存原来的属性值替换为 buf 里的属性值。
        • IPC_STAT:保存 shmid_ds 参数,把共享内存原来的属性值备份到 buf 里。
        • SHM_LOCK:锁定共享内存段( 超级用户 )。
        • SHM_UNLOCK:解锁共享内存段。
        • SHM_LOCK 用于锁定内存,禁止内存交换。并不代表共享内存被锁定后禁止其它进程访问。
      • buf:shmid_ds 数据类型的地址,用来存放或修改共享内存的属性。

  • 返回值: 成功0 ;失败-1

示例代码

  • 本例程未使用信号量,写端停留5秒等待读端读取信息,配合信号量使用的代码见文末

  • 写进程shm_w.c

    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    int main()
    {
         
        int shmid; //共享内存标识符
        char *shmaddr;
        key_t key;
        key = ftok(".",1);     //获取键值
        shmid = shmget(key,1024*4,IPC_CREAT|0666); //打开或者创建共享内存
        if(shmid == -1){
         
            printf("shmget NO OK\n");
            exit(-1);
        }
        shmaddr = shmat(shmid,0,0);  //共享内存连接到当前进程的地址空间
        printf("shmat ok\n");
        strcpy(shmaddr,"hello world"); //向内存中写入数据
        sleep(5);                 //睡眠5秒,等待内存数据被读走
        shmdt(shmaddr);            //断开进程和内存的连接
        shmctl(shmid,IPC_RMID,0);  //删除共享内存段
        printf("quit\n");
        return 0;
    }
    
    
  • 读进程shm_r.c

    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <stdio.h>
    #include <string.h>
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

money的大雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值