linux-进程通信(3)共享内存

共享内存

共享内存(Shared Memory),指两个或多个进程共享一个给定的存储区。

1.查看系统中的共享存储段:
ipcs -m
2.删除系统中的共享存储段:
ipcrm -m shmid(通过ipcs -m查看得到)

特点
1、共享内存是最快的一种 IPC,因为进程是直接对内存进行存取。

2、因为多个进程可以同时操作,所以需要进行同步。

3、信号量+共享内存通常结合在一起使用,信号量用来同步对共享内存的访问。
步骤
1、创建/打开共享内存(shmget)
2、进程A连接共享内存,写数据(shmat)
3、进程A断开连接(shmdt)
4、进程B连接共享内存,读数据
5、进程B断开连接
6、释放公共内存.(shmctl)
常用api


 // 创建或获取一个共享内存:成功返回共享内存ID,失败返回-1
 int shmget(key_t key, size_t size, int flag);

// 连接共享内存到当前进程的地址空间:成功返回指向共享内存的指针,失败返回-1
void *shmat(int shm_id, const void *addr, int flag);

// 断开与共享内存的连接:成功返回0,失败返回-1
 int shmdt(void *addr); 

 // 控制共享内存的相关信息:成功返回0,失败返回-1
 int shmctl(int shm_id, int cmd, struct shmid_ds *buf);

shmget

创建共享内存

函数原型

int shmget(key_t key, size_t size, int shmflg);

参数
key:由ftok生成的key标识

size:size以字节为单位指定需要共享的内存容量 ,在操作系统中,申请内存的最小单位为页,一页是4k字节,为了避免内存碎片,我们一般申请的内存大小为页的整数倍。

0:只获取共享内存时指定为0

shmflg:如果要创建新的共享内存,需要使用IPC_CREAT(要附上权限类似open函数的mode参数),IPC_CREAT | IPC_EXCL,如果是已经存在的,可以使用IPC_CREAT或直接传0。
返回值
成功返回共享内存的标识符;不成功返回-1,errno储存错误原因

shmat

第一次创建完共享内存时,它还不能被任何进程访问,shmat函数的作用就是用来启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间。

函数原型

void *shmat(int shm_id, const void *shm_addr, int shmflg); 

参数
shm_id:是由shmget函数返回的共享内存标识。
*shm_addr:指定共享内存连接到当前进程中的地址位置,通常为0
shm_flg:若指定了SHM_RDONLY位,则以只读方式连接此段,否则以读写方式连接此段(为0)

返回值
调用成功时返回一个指向共享内存第一个字节的指针,如果调用失败返回-1.

shmdt

该函数用于将共享内存从当前进程中断开。注意,并不是删除它,只是使该共享内存对当前进程不再可用。
函数原型

int shmdt(const void *shmaddr); 

参数
*shmaddr:是shmat函数返回的地址指针。
返回值
调用成功时返回0,失败时返回-1.

shmctl

函数原型

int shmctl(int shm_id, int command, struct shmid_ds *buf);  

参数
shm_id:shm_id是shmget函数返回的共享内存标识符。

command:command是要采取的操作,它可以取下面的三个值 :
IPC_STAT
IPC_SET
IPC_RMID 删除共享内存段

*buf:设置为0即可。

简单运用

//write

int main()
{
        key_t key;
        key=ftok(".",1);
        int shmId;
        char *shmAddr;
        shmId=shmget(key,1024*4,IPC_CREAT|0666);//创建共享内存,权限为可读可写可执行
        if(shmId==-1){
                printf("shmget failed\n");
        }
        shmAddr=shmat(shmId,0,0);//连接共享内存
        printf("shmaddr success\n");
        strcpy(shmAddr," ni hao ya !!!!!!!");//写入数据
        sleep(5);
        int k=shmdt(shmAddr);//断开连接
        printf("%d\n",k);//返回0,表示断开成功
        return 0;
}

//read

int main()
{
        key_t key;
        key=ftok(".",1);
        int shmId;
        char *shmAddr;
        shmId=shmget(key,1024*4,0);//打开共享内存
        if(shmId==-1){
                printf("shmget failed\n");
        }
        shmAddr=shmat(shmId,0,0);//连接共享内存
        printf("shmaddr success\n");
        printf("context:  %s\n",shmAddr);//打印出数据
        int k=shmdt(shmAddr);//断开连接
        printf("%d\n",k);
        shmctl(shmId,IPC_RMID,0);//删除共享内存
        return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值