Linux 进程间通信【共享内存】

本文深入解析了共享内存的概念,它是进程间通信的一种高效方式,允许多个进程访问同一段内存,实现数据共享。文章详细介绍了共享内存的Linux函数接口,如shmget(), shmat(), shmdt(), shmctl(),并通过示例代码展示了如何在进程间使用共享内存进行数据写入和读取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

共享内存

  • 什么是共享内存
    共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc()分配的内存一样。而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。
    特别提醒:共享内存并未提供同步机制,也就是说,在第一个进程结束对共享内存的写操作之前,并无自动机制可以阻止第二个进程开始对它进行读取。所以我们通常需要用其他的机制来同步对共享内存的访问,例如前面说到的信号量。
  • 共享内存的使用
    与信号量一样,在Linux中也提供了一组函数接口用于使用共享内存,而且使用共享共存的接口还与信号量的非常相似,而且比使用信号量的接口来得简单。它们声明在头文件 sys/shm.h 中。
    • shmget()函数
      该函数用来创建共享内存,它的原型为:
      int shmget(key_t key, size_t size, int shmflg);
      成功时返回一个与key相关的共享内存标识符(非负整数),用于后续的共享内存函数。调用失败返回-1.
    • shmat()函数
      第一次创建完共享内存时,它还不能被任何进程访问,shmat()函数的作用就是用来启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间。它的原型如下:
      void *shmat(int shm_id, const void *shm_addr, int shmflg);
      成功时返回一个指向共享内存第一个字节的指针,如果调用失败返回-1.
    • shmdt()函数
      该函数用于将共享内存从当前进程中分离。注意,将共享内存分离并不是删除它,只是使该共享内存对当前进程不再可用。它的原型如下:
      int shmdt(const void *shmaddr);
      调用成功时返回0,失败时返回-1.
    • shmctl()函数
      与信号量的semctl()函数一样,用来控制共享内存,它的原型如下:
      int shmctl(int shm_id, int command, struct shmid_ds *buf);
  • 例,进程A shmwrite.c 源码
  • #include <stdlib.h>
    #include <sys/types.h>  
    #include <sys/ipc.h>  
    #include <sys/shm.h>  
    #include <stdio.h>  
    #include <error.h>  
      
    #define SHM_SIZE    4096  
    #define SHM_MODE    (SHM_R | SHM_W) /* user read/write */  
      
    int main(void)  
    {  
        int  shmid;  
        char *shmptr;  
      
        if ( (shmid = shmget(0x44, SHM_SIZE, SHM_MODE | IPC_CREAT)) < 0)  
            perror("shmget");  
      
        if ( (shmptr = shmat(shmid, 0, 0)) == (void *) -1)  
            perror("shmat");  
          
        /* 往共享内存写数据 */  
        sprintf(shmptr, "%s", "hello, world");  
      
        exit(0);  
    } 

    进程B shmread.c 源码

  • #include <stdlib.h>
    #include <sys/types.h>  
    #include <sys/ipc.h>  
    #include <sys/shm.h>  
    #include <stdio.h>  
    #include <error.h>  
      
    #define SHM_SIZE    4096  
    #define SHM_MODE    (SHM_R | SHM_W | IPC_CREAT) /* user read/write */  
      
    int main(void)  
    {  
        int     shmid;  
        char    *shmptr;  
      
        if ( (shmid = shmget(0x44, SHM_SIZE, SHM_MODE | IPC_CREAT)) < 0)  
            perror("shmget");  
      
        if ( (shmptr = shmat(shmid, 0, 0)) == (void *) -1)  
            perror("shmat");  
      
        /* 从共享内存读数据 */  
        printf("%s\n", shmptr);  
      
        exit(0);  
    }

    编译

  • 运行

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值