共享内存 定义
共享内存是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);
}