Linux共享内存实验

1. 共享内存的优缺点 

共享内存是在系统内核分配的一块缓冲区,多个进程都可以访问该缓冲区。共享内存通信方式的优点是进程间传递信息最快,因为客户进程和服务进程传递的数据直接从内存里存取,数据不需要在两进程间复制。另外,共享内存的生命周期随内核,即所有访问共享内存区域对象的进程都已经正常结束,共享内存区域对象仍然在内核中存在(除非显式删除共享内存区域对象),在内核重新引导之前,对该共享内存区域对象的任何改写操作都将一直保留。简单地说,共享内存区域对象的生命周期跟系统内核的生命周期是一致的,而且共享内存区域对象的作用域范围就是在整个系统内核的生命周期之内。

 但是,共享内存也并不完美,系统没有为共享内存通信方式提供同步机制,即在一个服务进程结束对共享内存的写操作之前,并没有自动机制可以阻止另一个进程(客户进程)开始对它进行读取。这明显还达不到我们想要的,我们不单是在两进程间交互数据,还想实现多个进程对共享内存的同步访问。基于此,我们通常会用信号量来实现对共享内存同步访问控制。

2. 与内存共享相关的函数用法

(1) shmget()函数

功能:创建共享内存,函数用法如下表所示。

(2) shmctl()函数

功能:用于控制共享内存,函数用法如下表所示。

(3) shmat()函数

功能:将共享内存段连接到进程地址空间。

(4) shmdt()函数

功能:将共享内存段与当前进程脱离。该函数不从系统中删除标识符及其数据结构,要显示调用shmctl(带命令IPC_RMID)才能删除它。

3. 使用内存共享实现进程间通信

生成共享内存示例代码,shmcreat.c。

include<stdio.h>#include<stdlib.h>#include <sys/ipc.h>#include <sys/shm.h>#include<string.h>#include<errno.h>typedef struct _Teacher {    char name[64];    int age;}Teacher;
int main(int argc, char *argv[]){    int ret = 0;    int shmid;    //创建共享内存 ,相当于打开文件,文件不存在则创建    shmid = shmget(0x12345, sizeof(Teacher), IPC_CREAT | 0666);    if (shmid == -1) {        printf("shmget error.\n");        return errno;    }    printf("shmid:%d \n", shmid);    Teacher *p = NULL;    //将共享内存段连接到进程地址空间    p = shmat(shmid, NULL, 0);// 第二个参数为NULL,核心自动选择一个地址    if (p == (void *)-1 ) {        printf("shmget error.\n");        return errno;    }    strcpy(p->name, "aaaa");    p->age = 33;    //将共享内存段与当前进程脱离    shmdt(p);    printf("键入1 删除共享内存,其他不删除\n");    int num;    scanf("%d", &num);    if (num == 1)  {        //用于控制共享内存        ret = shmctl(shmid, IPC_RMID, NULL);//IPC_RMID为删除内存段        if (ret < 0) {            printf("rm error.\n");        }    }    return 0;}

编译运行程序,如下图所示,在键入1之前,执行ipcs -m可以看到key=0x12345的共享内存信息。

当键入1之后,key=0x12345的共享内存被删除,如下图所示。如果键入非1,则key=0x12345的共享内存在内核中一直存在。

获取共享内存信息源程序shmgetinfo.c。

include<stdio.h>#include<stdlib.h>#include <sys/ipc.h>#include <sys/shm.h>#include<string.h>#include<errno.h>
typedef struct _Teacher {    char name[64];    int age;}Teacher;
int main(int argc, char *argv[]){    int ret = 0;    int shmid;    //打开获取共享内存    shmid = shmget(0x12345, 0, 0);    if (shmid == -1)  {        printf("shmget error.\n");        return errno;    }    printf("shmid:%d \n", shmid);    Teacher *p = NULL;    //将共享内存段连接到进程地址空间    p = shmat(shmid, NULL, 0);    if (p == (void *)-1 ) {        printf("shmget error.\n");        return errno;    }    printf("name:%s\n", p->name);    printf("age:%d \n", p->age);    //将共享内存段与当前进程脱离    shmdt(p);    return 0;}

编译运行如下图所示。

运行./shmcreat创建shmid为24的共享内存,然后键入2程序运行结束。

运行./shmgetinfo从共享内存中读出./shmcreat写入共享内存的信息。

再次运行./shmgetinfo从共享内存中读出相同信息。

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lhw---9999

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

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

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

打赏作者

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

抵扣说明:

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

余额充值