[经验分享] C系统编程通信方式——共享内存

[复制链接]
16|0
xiaoqizi 发表于 2025-12-13 21:26 | 显示全部楼层 |阅读模式
       共享内存,标准IPC之一,也是进程间通信最快的一种方式。

1.概念
        所有的标准IPC都有一个内部ID作为唯一标识。内部ID的获取通过外部key,key的类型是key_t。key的获取方法有在头文件中定义所有key和通过ftok函数获取一个key。

key_t ftok(const char *pathname,int proj_id);
//pathname:有效的路径
//proj_id:非0的八位项目ID,一般采用一个字符




        通过key获取内部ID的函数都叫做xxxget。

        所有的标准IPC结构都提供一个xxxctl函数,该函数至少包含了查询,修改和删除的功能。

        所有IPC都是由内核管理,不需要手动删除。

2.共享内存(shared memory)
(1)原理
        内核以一块物理内存作为媒介,通常情况下一块物理内存只允许一个进程映射,共享内存实现了:允许所有进程对这块物理内存进行映射,当多个内存映射到这同一片内存空间时,便可以理解为进行了数据间的交换。

(2)编程使用
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/shm.h>
int main()
{
//1.获取key
key_t key=ftok("./",'x');
//2.使用shmget函数通过key创建/获取共享内存
int shmid=shmget(key,100,IPC_CREAT|0666);
//shmget参数一:上一步获取到的key,参数二:共享内存大小,参数三:创建时使用IPC_CREAT|0666
//3.使用shmat将共享内存映射到用户空间
char *p=shmat(shmid,NULL,0);
//shmat参数一:上一步获取的共享内存,参数二:映射地址,通常给零让系统自主选择,参数三:映射标志,通常给0
//4.像访问普通内存一样去访问共享内存(读/写)
//子进程写
if(!fork())
{
    while(1)
    {
        printf("请写入:");
        fgets(p,sizeof(p),stdin);
        strtok(p,"\n");
        printf("写入了%ld字节内容\n",strlen(p));
    }
}
//父进程读
while(1)
{
    printf("读到了%ld字节内容:%s\n",strlen(p),p);
    sleep(3);
}
//5.解除映射
shmdt(p);
return 0;
}



        以上只是使用例子,存在着实际不为合理的地方,供了解使用。

(3)shmctl函数
int shmctl(int shmid,int cmd,struct shmid_ds *buf);
//shmid:共享内存ID
//cmd:操作命令:IPC_STAT查询,IPC_SET修改,IPC_RMID删除
//buf:查询和修改时使用,查询时传出共享内存信息,设置时传入共享内存信息
struct shmid_ds {
   struct ipc_perm shm_perm;    /* 所有者和权限 */
   size_t          shm_segsz;   /* 共享内存大小 */
   time_t          shm_atime;   /* 最后挂接时间 */
   time_t          shm_dtime;   /* 最后脱接时间 */
   time_t          shm_ctime;   /* 最后一次修改时间 */
   pid_t           shm_cpid;    /* 创建者PID */
   pid_t           shm_lpid;    /* 最后挂接/脱接PID */
   shmatt_t        shm_nattch;  /* 当前挂接进程数 */
   ...
};

struct ipc_perm {
   key_t          __key;    /* key的值 */
   uid_t          uid;      /* --所有者ID */
   gid_t          gid;      /* --所有者组ID */
   uid_t          cuid;     /* 创建者ID */
   gid_t          cgid;     /* 创建者组ID */
   unsigned short mode;     /* --权限 + SHM_DEST and
                               SHM_LOCKED flags */
   unsigned short __seq;    /* Sequence number */
};
//其中只有uid,gid和mode可以修改



————————————————
版权声明:本文为CSDN博主「亦诚亦心」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/2303_76896902/article/details/143094084

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

160

主题

4572

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部
0