(本节笔记的实验代码,在这里)
1. 基本概念
共享内存是IPC机制中的一种,作用是使得两个不相关的进程访问同一段内存,是一种进程间传输数据的一种有效方式。
2. 函数学习
2.1 创建/获取共享内存
函数名:
shmget
函数原型: man shmget
int shmget(key_t key, size_t size, int shmflg);
函数功能:
创建或者获取共享内存,并返回其描述符(shmid)。
所属头文件:
<sys/ipc.h> <sys/shm.h>
返回值:
成功 :返回共享内存描述符(shmid) 失败 :返回-1
参数说明
key :共享内存的键值。
size :共享内存的大小。
shmflg :打开标志,如果使用了IPC_CREAT,则会新创建一块共享内存。
2.2 映射共享内存
函数名:
shmat
函数原型: man shmat
void *shmat(int shmid, const void *shmaddr, int shmflg);
函数功能:
把shmid指定的共享内存映射到进程的地址空间里。
所属头文件:
<sys/types.h> <sys/shm.h>
返回值:
成功 :返回映射到进程空间之后的内存地址 失败 :返回-1
参数说明:
shmid :要映射的共享内存的描述符。
*shmaddr :指定映射到进程空间里的地址,为避免地址冲突,一般使用NULL,让系统自动分配映射地址。
shmflg :标志。
2.3 脱离共享内存
函数名:
shmdt
函数原型:man shmdt
int shmdt(const void *shmaddr);
函数功能:
从进程地址空间中断掉与共享内存的联系。
所属头文件:
<sys/types.h> <sys/shm.h>
返回值:
成功 :返回0 失败 :返回-1
参数说明:
*shmaddr :要断开的共享内存的映射地址。
2.4 删除共享内存
函数名:
shmctl
函数原型: man shmctl
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
函数功能:
控制共享内存。
所属头文件:
<sys/ipc.h> <sys/shm.h>
返回值:
成功 :根据的操作返回不同的值 失败 :返回-1
参数说明:
shmid :要控制的共享内存id。
cmd :要执行什么样的控制操作,如IPC_RMID表示删除。
*buf :获取Linux中描述共享内存的shmid_ds结构,该参数基本不用。
2.5 获取用户输入的字符串
函数名:
fgets
函数原型: man fgets
char *fgets(char *s, int size, FILE *stream);
函数功能:
获取用户从键盘上的输入的字符串。
所属头文件:
<stdio.h>
返回值:
成功 :返回字符串的地址? 失败 :?
参数说明:
*s :获取到的字符串放到哪里。
size :要放入多大的字符串。
*stream :从哪里获取的字符串。
2.6 复制字符串
函数名:
strncpy
函数原型: man strncpy
char *strncpy(char *dest, const char *src, size_t n);
函数功能:
把一个地址的字符串复制到另一个地址。
所属头文件:
<string.h>
返回值:
成功 :返回字符串的地址? 失败 :?
参数说明:
dest :目的地址。
src :原地址。
n :复制的字符串大小。
3. 综合实例
/* touch write.c */
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define TEXT_SZ 2048
struct shared_user_st
{
int written_by_you;
char some_text[TEXT_SZ];
};
int main()
{
int shmid;
int running = 1;
char buffer[TEXT_SZ];
struct shared_user_st *shared_stuff;
//1.创建共享内存
shmid = shmget((key_t)1234, sizeof(struct share_user_st), IPC_CREAT);
if(-1 == shmid)
{
printf("creat share memory fail!\n");
exit(EXIT_FAILURE);
}
//2.映射共享内存
shared_stuff = (struct shared_user_st *)shmat(shmid, NULL, 0);
//3.循环获取用户输入字符串并放入共享内存
while(running)
{
while(1 == shared_stuff->written_by_you)
{
sleep(1);
printf("wait read process!\n");
}
fgets(buffer, TEXT_SZ, stdin);
strncpy(shared_stuff->some_text, buffer, TEXT_SZ);
shared_stuff->written_by_you = 1;
if(0 == strncmp(buffer, "end", 3))
{
running = 0;
}
}
//4.脱离共享内存
shmdt((const void *)shared_stuff);
return 0;
}
/* touch read.c */
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define TEXT_SZ 2048
struct shared_user_st
{
int written_by_you;
char some_text[TEXT_SZ];
};
int main()
{
int shmid;
int running = 1;
struct shared_user_st *shared_stuff;
//1.创建/获取共享内存
shmid = shmget((key_t)1234, sizeof(struct share_user_st), IPC_CREAT);
if(-1 == shmid)
{
printf("creat share memory fail!\n");
exit(EXIT_FAILURE);
}
//2.映射共享内存
shared_stuff = (struct shared_user_st *)shmat(shmid, NULL, 0);
shared_stuff->written_by_you = 0;
//3.循环打印共享内存
while(running)
{
if(1 == shared_stuff->written_by_you)
{
printf("write process write %s\n", shared_stuff->some_text);
}
if(0 == strncmp(shared_stuff->some_text, "end", 3))
{
running = 0;
}
}
//4.脱离共享内存
shmdt((const void *)shared_stuff);
//5.删除共享内存
shmctl(shmid, IPC_RMIC, 0);
return 0;
}