linux系统编程——进程共享内存通信

~共享内存概述:
共享内存,就是允许两个或者多个不同的进程访问同一个给定的内存,因为数据不需要在进程复制,所以共享内存是最快的一种IPC,不同的进程将同一段物理地址映射到各自的进程中,如果一个进程向共享内存写数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。
~注:当一个进程在共享内存处写入数据时不应该别的进程去读(共享内存不提供同步机制)。
~注:它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。

1,共享内存相关的API

 #include <sys/ipc.h>
 #include <sys/shm.h>

int shmget(key_t key, size_t size, int shmflg);//获取共享内存
//参数1:系统使用共享内存时必须有ID号(用ftok获取)
//参数2:龚翔内存空间(以1024byte为单位);
//参数3:一般为IPC_CREAT|0600创建一个键值和key相等的可读可写的内存
 void *shmat(int shmid, const void *shmaddr, int shmflg);//将共享内存映射到改进程的地址空间中
//参数1:共享内存的标识符(ID)
//参数2:指定共享内存出现在进程内存地址的什么位置
//参数3:SHM_RDONLY读只读模式其他为读写
 int shmdt(const void *shmaddr);//禁止共享内存连接到进程地址空间
 int shmctl(int shmid, int cmd, struct shmid_ds *buf);//对共享内存进行移除等控制
//参数1:shm_id是shmget函数返回的共享内存标识符。

//参数2:command是要采取的操作,它可以取下面的三个值 :
    IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。
    IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值
    IPC_RMID:删除共享内存段

//参数3:buf是一个结构指针,它指向共享内存模式和访问权限的结构。
shmid_ds结构至少包括以下成员:

2,共享内存简单的代码实现;
read.c文件用于读共享内存数据,write.c用于往共享内存中写数据(写入hello world!)。
write.c文件如下:

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <stdlib.h>

int main()
{
        int shmid;
        key_t key;
        key = ftok(".",1);
        char *shmaddr;
        shmid = shmget(key,1024*6,IPC_CREAT|0666);//创建或者得到一个键值与key相等的共享内存ID号
        if(shmid == -1)
        {
                printf("shmget failed!\n");
                exit(0);
        }

        shmaddr = shmat(shmid,0,0);//映射共享内存地址到该进程的地址空间
       
        strcpy(shmaddr,"hello world!");

        sleep(5);//等待5s让别的进程读取内存数据
        
        shmdt(shmaddr);//和该进程解除地址映射
        shmctl(shmid,IPC_RMID,0);//删除共享内存,不关心它的删除返回值

                                        

read.c文件代码如下:

#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <stdlib.h>

int main()
{
        int shmid;
        key_t key;
        key = ftok(".",1);
        char *shmaddr;
        shmid = shmget(key,1024*4,0);//在write.c文件中已经得到了键值与key相等的共享内存所以不需要创建
        if(shmid == -1)
        {
                printf("shmget failed!\n");
                exit(0);
        }

        shmaddr = shmat(shmid,0,0);
        printf("shmat ok!\n");
        printf("data = %s\n",shmaddr);

        shmdt(shmaddr);

        return 0;
}

注:先让write.c先写入共享内存,然后read.c去读,保证在5秒内不然read会报错(在write执行5秒后移除了共享内存)

注:IPC中键值的作用:
进程间的通讯,必须要有个公共的标识来确保使用同一通讯通道(比如通道为共享内存),然后再把这个标识与某个共享内存进行绑定,任何一个进程如果使用相同一个标识,则内核就可以通过标识来找到对应的那段共享内存,这个标识就是键值。如果没有键值,一个进程打开或者创建一个共享内存并返回ID,但是其他想要通信的进程不知道这个共享内存的ID是多少,所以就不能通讯了。
命令扩展

ipcs -m//查看共享存储段
ipcrm -m [shmid]//删除系统共享存储段
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值