[Linux]内存共享

API


头文件

#include <shm.h>

创建共享内存

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

key:键值,有效地为共享内存段命名
size:申请内存的大小

获取创建好的共享内存

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

shm_id:由shmget创建返回的共享内存id
shm_addr:指定物理共享内存映射到当前进程的此地址处,设为NULL时由OS决定

分离获得的共享内存

int shmdt(void *shm_addr);

shm_addr:shmat返回的本进程映射地址。
该函数只是让共享内存不再映射到本进程的地址范围内,并非释放共享内存

对共享内存进行操作

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

struct shmid_ds{
uid_t shm_perm.uid;
uid_t shm_perm.gid;
mode_t shm_perm.mode;
};
comman:

IPC_STAT
把shmid_ds中的数据设为共享内存的当前关联值
IPC_SET
如果有权限,把共享内存的内容设为shmid_ds中的数据
IPC_RMID
删除共享内存段


Console下的通信

头文件

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

#define TEXT_SZ 2048

struct shared_use_st{
    int written_by_you;
    char some_text[TEXT_SZ];
};

Producer.c

#include "shm_com.h"

int main()
{
    int running = 1;
    void *shared_memory = NULL;
    struct shared_use_st *shared_stuff;
    char buffer[BUFSIZ];
    int shmid;

    //创建共享内存
    shmid = shmget((key_t)2222, sizeof(struct shared_use_st), 0666|IPC_CREAT);

    if(shmid == -1){
        fprintf(stderr, "shmget failed.\n");
        return 1;
    }

    //获取共享内存映射
    shared_memory = shmat(shmid, NULL ,0);
    if(shared_memory == (void *)-1){
        fprintf(stderr, "shmat failed.\n");
        return 1;
    }
    printf("Memory attached at %X.\n", (int)shared_memory);
    shared_stuff = (struct shared_use_st *)shared_memory;
    while(running){
        //等待消费者改写数据(表示有消费者存在)
        while(shared_stuff->written_by_you == 1){
            sleep(1);
            printf("Waiting for client ...\n");
        }
        printf("Enter some text: ");
        fgets(buffer, BUFSIZ, stdin);

        strncpy(shared_stuff->some_text, buffer, TEXT_SZ);
        shared_stuff->written_by_you = 1;

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

    //解除内存映射关系
    if(shmdt(shared_memory) == -1){
        fprintf(stderr, "shmdt failed.\n");
        return 1;
    }

    return 0;
}

Consumer.c

#include "shm_com.h"

int main()
{
    int running = 1;
    void *shared_memory = NULL;
    struct shared_use_st *shared_stuff;
    int shmid;


    //创建共享内存
    shmid = shmget((key_t)2222, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
    if(shmid == -1){
        fprintf(stderr, "shmget failed.\n");
        return 1;
    }

    //将共享内存地址映射到本进程
    shared_memory = shmat(shmid, NULL, 0);
    if(shared_memory == (void*)-1){
        fprintf(stderr, "shmat failed.\n");
        return 1;
    }

    printf("Memory attached at %X.\n", (int)shared_memory);

    shared_stuff = (struct shared_use_st *)shared_memory;
    shared_stuff -> written_by_you = 0;
    while(running){
        if(shared_stuff->written_by_you){
            printf("You wrote:%s\n",shared_stuff->some_text);
            sleep(rand()%4);
            shared_stuff->written_by_you = 0;
            if(strncmp(shared_stuff->some_text, "end", 3) == 0){
                running = 0;
            }
        }
    }

    //分离共享内存
    if(shmdt(shared_memory) == -1){
        fprintf(stderr, "shmdt failed.\n");
        return 1;
    }

    //释放共享内存
    if(shmctl(shmid, IPC_RMID, 0) == -1){
        fprintf(stderr, "shmctl(IPC_RMID) failed.\n");
        return 1;
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值