1.什么是共享内存?
与共享内存有关的函数
所有的函数共用头文件
1
2
3
|
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
|
创建共享内存——>shmget() 函数
1
2
|
int
shmget(key_t key,
size_t
size,
int
shmflg);
//成功返回共享内存的ID,出错返回-1
|
1
2
|
int
shmctl(
int
shm_id,
int
cmd,
struct
shmid_ds *buf);
//成功返回0,出错返回-1
|
1
2
3
4
5
6
|
struct
shmid_ds
{
uid_t shm_perm.uid;
uid_t shm_perm.gid;
mode_t shm_perm.mode;
};
|
挂接操作———>shmat()函数
创建共享存储段之后,将进程连接到它的地址空间
1
2
|
void
*shmat(
int
shm_id,
const
void
*shm_addr,
int
shmflg);
//成功返回指向共享存储段的指针,出错返回-1
|
(1)第一个参数,shm_id是由shmget函数返回的共享内存标识。
(2)第二个参数,shm_addr指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。
(3)第三个参数,shm_flg是一组标志位,通常为0
3.4分离操作———>shmdt()函数
1
2
|
int
shmdt(
const
void
*shmaddr);
//成功返回0,出错返回-1
|
4.模拟实现进程间的通信方式———>共享内存
shmdata.h的源代码如下:
1
2
3
4
5
6
7
8
9
|
#ifndef _SHMDATA_H_HEADER
#define _SHMDATA_H_HEADER
#define TEXT_SZ 2048
struct
shared_use_st
{
int
written;
//作为一个标志,非0:表示可读,0表示可写
char
text[TEXT_SZ];
//记录写入和读取的文本
};
#endif
|
源文件shmread.c的源代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/shm.h>
#include "shmdata.h"
int
main()
{
int
running = 1;
//程序是否继续运行的标志
void
*shm = NULL;
//分配的共享内存的原始首地址
struct
shared_use_st *shared;
//指向shm
int
shmid;
//共享内存标识符 //创建共享内存
shmid = shmget((key_t)1234,
sizeof
(
struct
shared_use_st), 0666|IPC_CREAT);
if
(shmid == -1)
{
fprintf
(stderr,
"shmget failed\n"
);
exit
(EXIT_FAILURE);
}
//将共享内存连接到当前进程的地址空间
shm = shmat(shmid, 0, 0);
if
(shm == (
void
*)-1)
{
fprintf
(stderr,
"shmat failed\n"
);
exit
(EXIT_FAILURE);
}
printf
(
"\nMemory attached at %X\n"
, (
int
)shm);
//设置共享内存
shared = (
struct
shared_use_st*)shm;
shared->written = 0;
while
(running)
//读取共享内存中的数据
{
//没有进程向共享内存定数据有数据可读取
if
(shared->written != 0)
{
printf
(
"You wrote: %s"
, shared->text);
sleep(
rand
() % 3);
//读取完数据,设置written使共享内存段可写
shared->written = 0;
//输入了end,退出循环(程序)
if
(
strncmp
(shared->text,
"end"
, 3) == 0)
running = 0;
}
else
//有其他进程在写数据,不能读取数据
sleep(1);
}
//把共享内存从当前进程中分离
if
(shmdt(shm) == -1)
{
fprintf
(stderr,
"shmdt failed\n"
);
exit
(EXIT_FAILURE);
}
//删除共享内存
if
(shmctl(shmid, IPC_RMID, 0) == -1)
{
fprintf
(stderr,
"shmctl(IPC_RMID) failed\n"
);
exit
(EXIT_FAILURE);
}
exit
(EXIT_SUCCESS);
}
|
源文件shmwrite.c的源代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include "shmdata.h"
int
main()
{
int
running = 1;
void
*shm = NULL;
struct
shared_use_st *shared = NULL;
char
buffer[BUFSIZ + 1];
//用于保存输入的文本
int
shmid;
//创建共享内存
shmid = shmget((key_t)1234,
sizeof
(
struct
shared_use_st), 0666|IPC_CREAT);
if
(shmid == -1)
{
fprintf
(stderr,
"shmget failed\n"
);
exit
(EXIT_FAILURE);
}
//将共享内存连接到当前进程的地址空间
shm = shmat(shmid, (
void
*)0, 0);
if
(shm == (
void
*)-1)
{
fprintf
(stderr,
"shmat failed\n"
);
exit
(EXIT_FAILURE);
}
printf
(
"Memory attached at %X\n"
, (
int
)shm);
//设置共享内存
shared = (
struct
shared_use_st*)shm;
while
(running)
//向共享内存中写数据
{
//数据还没有被读取,则等待数据被读取,不能向共享内存中写入文本
while
(shared->written == 1)
{
sleep(1);
printf
(
"Waiting...\n"
);
}
//向共享内存中写入数据
printf
(
"Enter some text: "
);
fgets
(buffer, BUFSIZ, stdin);
strncpy
(shared->text, buffer, TEXT_SZ);
//写完数据,设置written使共享内存段可读
shared->written = 1;
//输入了end,退出循环(程序)
if
(
strncmp
(buffer,
"end"
, 3) == 0)
running = 0;
}
//把共享内存从当前进程中分离
if
(shmdt(shm) == -1)
{
fprintf
(stderr,
"shmdt failed\n"
);
exit
(EXIT_FAILURE);
}
sleep(2);
exit
(EXIT_SUCCESS);
}
|
结果截图如下: