【C语言】【unix c】共享内存

110 篇文章 1 订阅
一、共享内存
    1、获取一个键值 ftok(32、使用键值获取共享内存的ID shmget(2#include <sys/ipc.h>
            #include <sys/shm.h>
            int shmget(key_t key, size_t size, int shmflg);
            功能:分配一块共享内存段,获取和key值相关的共享内存段的ID
            参数:
                key:ftok(3)的返回值
                size:指定共享内存段的尺寸
                shmflg:
                IPC_CREAT:如果没有和key值相关的内存段就创建
                IPC_EXCL:如果有相关的内存段报错(和IPC_CREAT一起存在时)
                mode:指定共享内存段的权限
            返回值:-1 错误 errno被设置
                成功 返回共享内存段的ID
        编写代码创建一个共享内存段,获取该内存段的id(shmget.c)

            #include <stdio.h>
            #include <sys/ipc.h>
            #include <sys/shm.h>
            #include <sys/types.h>
            int main(void) {
                key_t key; //用于存储键值
                //获取键值
                key = ftok(".", 31);
                if(key == -1) {
                perror("ftok");
                return -1;
                }
                printf("key=0x%x\n",key);
                //获取shmid
                int shmid = shmget(key, 1024, IPC_CREAT|0664);
                if(shmid == -1) {
                perror("shmget");
                return -1;
                }
                printf("shmid=0x%x\n", shmid);
                return 0;
            }

            tarena@ubuntu:~/day/day34$ a.out 
            key=0x1f08241a
            shmid=0x10001

            tarena@ubuntu:~$ ipcs -m

            ------ Shared Memory Segments --------
            key        shmid      owner      perms      bytes      nattch     status      
            0x00000000 0          tarena     600        393216     2          dest         
            0x1f08241a 65537      tarena     664        1024       0                       

    3、将共享内存关联到进程的虚拟地址空间shmat(2)
        #include <sys/types.h>
        #include <sys/shm.h>
        void *shmat(int shmid, const void *shmaddr, int shmflg);
            功能:将一块共享内存段添加到内存的地址空间
            参数:
                shmid:指定了共享内存段的ID
                shmaddr:NULL 由系统选择地址
                shmflg:
                    SHM_RDONLY:共享内存段只读
                    0:可都可写
            返回值:成功 返回附加到进程内存段的地址
                错误 (void *) -1 errno被设置

    4、向内存读写数据
    5、解除进程的虚拟地址到共享内存的关联shmdt(2#include <sys/types.h>
        #include <sys/shm.h>
        int shmdt(const void *shmaddr);
            功能:解除共享内存段和进程地址空间的关联
            参数:
                shmaddr:指定了共享内存段的起始地址
            返回值:成功 0
                错误 -1 errno被设置

        举例:使用共享内存段实现进程间的通信(shmA.c shmB.c)

        shmA.c:
            #include <stdio.h>
            #include <sys/ipc.h>
            #include <sys/shm.h>
            #include <sys/types.h>
            int main(void) {
                key_t key; 
                key = ftok(".", 31);
                if(key == -1) {
                perror("ftok");
                return -1;
                }
                printf("key=0x%x\n",key);
                int shmid = shmget(key, 1024, IPC_CREAT|0664);
                if(shmid == -1) {
                perror("shmget");
                return -1;
                }
                //将共享内存段附加到进程的地址空间
                void *p = shmat(shmid, NULL, 0);
                if(p == (void*)-1) {
                perror("shmat");
                return -1;
                }
                *((int*)p) = 321;//p的访问方式由void*转换为int*
                //解除关联
                shmdt(p);
                printf("shmid=0x%x\n", shmid);
                return 0;
            }

        命令: tarena@ubuntu:~/day/day34$ A
        结果: key=0x1f08241a
            shmid=0x10001

        shmB.c:
            #include <stdio.h>
            #include <sys/ipc.h>
            #include <sys/shm.h>
            #include <sys/types.h>
            int main(void) {
                key_t key; 
                key = ftok(".", 31);
                if(key == -1) {
                perror("ftok");
                return -1;
                }
                printf("key=0x%x\n",key);
                int shmid = shmget(key, 1024, IPC_CREAT|0664);
                if(shmid == -1) {
                perror("shmget");
                return -1;
                }
                //将共享内存段附加到进程的地址空间
                void *p = shmat(shmid, NULL, 0);
                if(p == (void*)-1) {
                perror("shmat");
                return -1;
                }
                printf("%d\n",*((int*)p));
                //解除关联
                shmdt(p);
                printf("shmid=0x%x\n", shmid);
                return 0;
            }

        命令: tarena@ubuntu:~/day/day34$ B
        结果: key=0x1f08241a
            321
            shmid=0x10001


        分析:共享内存中,在取出数据后,内存中还有数据,只能覆盖不能移除,和消息队列不太一样
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

刘星燎

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

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

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

打赏作者

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

抵扣说明:

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

余额充值