前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >进程间通信 共享内存

进程间通信 共享内存

作者头像
开源519
发布2021-09-16 15:09:39
1K0
发布2021-09-16 15:09:39
举报
文章被收录于专栏:开源519开源519

共享内存指 (shared memory)在多处理器的计算机系统中,可以被不同中央处理器(CPU)访问的大容量内存。--百度百科

上述已经将共享内存的概念说的很清晰了,简单理解就是多个进程可共用一片存储内存。

Linux已经提供了共享内存的接口,本文主要简单介绍此接口使用方法及使用实例。

接口说明

设置共享存储标识符: 设定共享内存的标识符,用于读写时唯一许可。

代码语言:javascript
复制
/**
 * @brief: returns  the identifier of the System V shared memory 
 * segment associated with the value of the argument key.
 *
 * @param - key: identification of the IPC
 * @param - size: the size of shared memory usage
 * @param - shmflg: If  shmflg specifies both IPC_CREAT and IPC_EXCL 
 * and a shared memory segment already exists for key, then shmget() 
 * fails with errno set to EEXIST.
 * 
 * @return On success, a valid shared memory identifier is returned.  
 * On error, -1 is returned, and errno is set to indicate the error.
 */
int shmat(key_t key, size_t size, int shmflg)

将共享字段链接到地址空间 设定共享内存字段在系统的存储地址。

代码语言:javascript
复制
/**
 * @brief: shmat() attaches the System V shared memory segment 
 * identified by shmid to the address space of the calling process.
 *
 * @param - shmid: 
 * @param - shmaddr:  the addr of the System V shared memory
 * @param - shmflg: 
 *
 * @return On success, shmat() returns the address of the attached 
 * shared memory segment; 
 * on error, (void *) -1 is returned, and errno is  set to indicate 
 * the cause of the error.
 */
void *shmat(int shmid, const void *shmaddr, int shmflg)

取消共享地址映射 当共享内存使用完毕后,调此接口会结束共享内存与指定的系统地址的映射关系。这里并未从系统中删除标识符,该标识符一直存在直至某个进程带IPC_RMID命令调用shmctl特地删除它为止。

代码语言:javascript
复制
/**
 * @brief: detaches  the  shared  memory  segment  located  at the 
 * address specified by shmaddr from the address space of the calling 
 * process.
 *
 * @param - shmaddr:  the addr of the System V shared memory
 *
 * @return On success, shmdt() returns 0; 
 * on error -1 is returned, and errno is set to indicate the cause of 
 * the error.
 */
int shmdt(const void *shmaddr);

共享内存多种操作 类似于驱动ctrl函数,即传入不同的命令可执行不同的操作。cmd可选择IPC_STAT/IPC_SET/IPC_RMID/SHM_LOCK/SHM_UNLOCK。 IPC_STAT 将与shmid关联的内核数据结构中的信息复制到buf所指向的shmid_ds结构中。 IPC_SET 将buf指向的shmid_ds结构的一些成员的值写入与这个共享内存段相关联的内核数据结构,同时更新它的shm_ctime成员。 IPC_RMID 标记要销毁的共享内存。只有在最后一个进程将它分离之后,共享内存才会被销毁。 SHM_LOCK 防止读取共享内存。 SHM_UNLOCK 解锁共享内存,允许它被读取出来。

代码语言:javascript
复制
/**
 * @brief: performs the control operation specified by cmd on the 
 * System V shared memory segment whose identifier is given in shmid.
 *
 * @param - shmid: 
 * @param - cmd: 
 * @param - buf: 
 *
 * @return A successful IPC_INFO or SHM_INFO operation returns the
 * index of the highest used entry in the kernel's  internal  array  recording
 * information  about  all shared memory segments.  (This information
 * can be used with repeated SHM_STAT or SHM_STAT_ANY operations 
 * to obtain information about all shared memory segments on the system.)
 * A successful SHM_STAT operation returns the identifier of  the shared 
 * memory segment whose index was given in shmid.  Other operations 
 * return 0 on success.
 * On error, -1 is returned, and errno is set appropriately.
 */
int shmctl(int shmid, int cmd, struct shmid_ds *buf)

实例演示

功能: 使用共享内存设计两个读写进程,实现跨进程通信。演示:

总结

本文主要接收共享内存接口的简单使用实例,其可通过shmctl传输不同的指令实现比较高级的用法,例如权限限制。其中共享内存也可以配合其他机制实现一套比较好用的通信策略,后续可以玩一玩。

代码

read.cpp

代码语言:javascript
复制
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include "common.h"

int main(int argc, char *argv[])
{
    int shmid, running = 1;
    void *shm = NULL;
    struct ShmData *pShareData = NULL;

    shmid = shmget((key_t)SHM_NAME, sizeof(struct ShmData), 0666|IPC_CREAT);
    if (shmid == -1) {
        printf("shmget failed!\n");
        exit(0);
    }

    shm = shmat(shmid, 0, 0);
    if (shm == (void*)-1) {
        printf("shmat failed!\n");
        exit(0);
    }
    printf("Memory attached at %p\n", shm);

    pShareData = (struct ShmData *)shm;
    pShareData->flag = 0;

    while (running) {
        if (pShareData->flag) {
            printf("The memery data: %s", pShareData->data);
            sleep(rand() % 3);
            pShareData->flag = 0;

            if (!strncmp(pShareData->data, "end", 3)) {
                running = 0;
            }

        } else {
            sleep(1);
        }
    }

    printf("Over!\n");
    if (shmdt(shm) == -1) {
        printf("shmdt failed!\n");
        exit(0);
    }

    if (shmctl(shmid, IPC_RMID, 0) == -1) {
        printf("shmctl failed!\n");
        exit(0);
    }

    return 0;
}

write.cpp

代码语言:javascript
复制
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include "common.h"

int main(int argc, char *argv[])
{
    int shmid, running = 1;
    char buffer[DATA_SIZE+1] = {0};
    void *shm = NULL;
    struct ShmData *pShareData = NULL;

    shmid = shmget((key_t)SHM_NAME, sizeof(struct ShmData), IPC_EXCL);
    if (shmid == -1) {
        printf("shmget failed!\n");
        exit(0);
    }

    shm = shmat(shmid, (void*)0, 0);
    if (shm == (void*)-1) {
        printf("shmat failed!\n");
        exit(0);
    }
    printf("Memory attached at %p\n", shm);

    pShareData = (struct ShmData *)shm;
    //pShareData->flag = 0;

    while (running) {
        while (pShareData->flag == 1) {
            sleep(1);
            printf("Waiting...\n");
        }

        printf("Input data: ");
        fgets(buffer, DATA_SIZE, stdin);
        strncpy(pShareData->data, buffer, DATA_SIZE);
        pShareData->flag = 1;

        if (strncmp(buffer, "end", 3) == 0) {
            running = 0;
        }
    }

    if (shmdt(shm) == -1) {
        printf("shmdt failed!\n");
        exit(0);
    }
    sleep(2);

    return 0;
}

最后

用心感悟,认真记录,写好每一篇文章,分享每一框干货。愿每一篇文章不负自己,不负看客!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-09-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源519 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 接口说明
  • 实例演示
  • 总结
    • 代码
      • 最后
      相关产品与服务
      对象存储
      对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档