共享内存 进程间通信

共享内存 定义

共享内存是IPC机制中的一种。顾名思义,它允许两个不相关的进程访问同一段内存,这是传递数据的一种非常有效的方式。

创建和打开共享内存

函数原形:
int shmget(key_t key, size_t size, int shmflg);

函数功能:
创建或者获取一块共享内存。

所属头文件:

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

返回值:
若成功,返回共享内存的标识符ID;若失败,返回-1.

参数说明:
key:共享内存的键值。
size:共享内存的大小。
shmflg:标志,尤其是IPC_CREAT,直接创建一块新的共享内存。

映射共享内存

函数原形:
void *shmat(int shmid, const void *shmaddr, int shmflg);

函数功能:
将shmid所标识的共享内存映射在进程的地址空间中。

所属头文件:

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

返回值:
若成功,返回共享内存的映射地址;若失败,返回-1.

参数说明:
shmid:共享内存的标识符。
shmaddr:共享内存的地址。一般情况下为NULL,由系统 指定合适的位置。
shmflg:标志。若没有特殊标志,为0。

分离共享内存

函数原形:
int shmdt(const void *shmaddr);

函数功能:
从进程地址空间中,断开映射的共享内存

所属头文件:

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

返回值:
若成功返回0,若失败返回-1

参数说明:
shmaddr:要断开的共享内存的映射地址。

操作共享内存

函数原形:
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

函数功能: 操作共享内存。

所属头文件:

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

返回值:
若成功,根据操作返回相应数值;若失败,返回-1。

参数说明:
shmid:共享内存的标识符ID。
cmd:要进行的操作。如删除共享内存IPC_RMID
buf:获取linux定义的描述共享内存的shmid_ds结构体,但一般不使用。设为NULL。

例程:

1、向共享内存中写内容:

/* 本文件关于共享内存的代码,这是写文件 */
/* 首先,一个进程将数据写入共享内存中 */
/* 然后,另一个进程将数据从共享内存中读出来 */
/* read先运行 */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TEXT_SZ 2048 //2KB,数据长度

struct shared_usr_st
{
    int writen_by_you;//标志位,写完后标志位置1,如果不读走一直是1,
    //只有读走之后变为0。如果标志=1,则write进程进行等待。
    char some_text[TEXT_SZ];//存放数据
};

void main()
{
    int running = 1;
    int shmid;//共享内存ID
    key_t key;//键值
    struct shared_usr_st *shared_stuff;//定义结构指针
    char buffer[TEXT_SZ];

    //创建键值
    key = ftok("./key", 1);//路径 项目ID

    //1、创建共享内存
    shmid = shmget(key, sizeof(struct shared_usr_st), IPC_CREAT);
    if (shmid == -1)//判断是否正确创建
    {
        printf("creat shared memory fail.\n");
        exit(EXIT_FAILURE); //退出程序
    }

    //2、映射共享内存
    shared_stuff = (struct shared_usr_st *)shmat(shmid, NULL, 0);
    //做一个强制转换,没有特殊标志,标志为0,系统自动分配地址

    //3、循环
    while (running)
    {
        //如果之前的数据没有取走,则等待
        while(shared_stuff -> writen_by_you == 1)
        {
            sleep(1);
            printf("wait read process.\n");
        }

        //3.1获取用户输入
        fgets(buffer, TEXT_SZ, stdin);

        //3.2将用户输入的字符串放进内存
        strncpy(shared_stuff -> some_text, buffer, TEXT_SZ);
        shared_stuff -> writen_by_you = 1;//写完了,可以开始读了

        if (strncmp(buffer, "end", 3) == 0)
        //如果用户输入的字符串为end,结束
            running = 0;
    }

    //4、脱离共享内存
    shmdt((const void *)shared_stuff);
}

2、从共享内存中读内容

/* 本文件关于共享内存的代码,这是读文件 */
/* 首先,一个进程将数据写入共享内存中 */
/* 然后,另一个进程将数据从共享内存中读出来 */
/* read先运行 */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TEXT_SZ 2048 //2KB,数据长度

struct shared_usr_st
{
    int writen_by_you;//标志位,写完后标志位置1,如果不读走一直是1,
    //只有读走之后变为0。如果标志=1,则write进程进行等待。
    char some_text[TEXT_SZ];//存放数据
};

void main()
{
    int running = 1;
    int shmid;//共享内存ID
    key_t key;//键值
    struct shared_usr_st *shared_stuff;//定义结构指针

    //创建键值
    key = ftok("./key", 1);//路径 项目ID

    //1.创建获取共享内存
    shmid = shmget(key, sizeof(struct shared_usr_st), IPC_CREAT);

    //2.映射共享内存
    shared_stuff = (struct shared_usr_st *)shmat(shmid, NULL, 0);

    shared_stuff -> writen_by_you = 0;//赋初值,read先运行
    //3.循环
    while(running)
    {
        //如果标志位为1,表明写入了数据,可以开始读数据了
        if(shared_stuff -> writen_by_you == 1)
        {
            //3.1打印共享内存中的数据
            printf("write process write %s", shared_stuff -> some_text);
            shared_stuff -> writen_by_you = 0;//表明读完了,可以开始写了

            if (strncmp(shared_stuff -> some_text, "end", 3) == 0)
            //如果用户输入的字符串为end,结束
                running = 0;
        }
    }
    //4.脱离共享内存
    shmdt((const void *)shared_stuff);

    //5.删除共享内存  
    shmctl(shmid, IPC_RMID, NULL);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值