进程间通信之共享内存

共享内存(SHared Memory,SHM)不需要在进程间来回复制数据,是最快的进程间通信(Inter-Process Communication,IPC)方式。

实现原理

共享内存

系统库函数

共享内存相关的方法位于sys/shm.h,共包含了四个方法:

1
2
3
4
5
// 返回共享内存的唯一标识符
int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

其中,at表示attach,dt表示detach。

此外,系统库中还提供了函数ftok(),用于生成进程间通信的键值。该函数位于sys/ipc.h中:

1
key_t   ftok(const char *fname, int id);

常用模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 1.根据文件路径名和id,得到键值
key_t key = ftok(".", 1);

// 2.创建共享内存,并设置共享内存的大小、访问权限
int shm_id = shmget(key, 65535, IPC_CREAT | 0644);

// 3.连接共享内存
void *shm = shmat(shm_id, 0, 0);

// 4.读写共享内存

// 5.断开连接
shmdt(shm_id);

// 6.删除共享内存
shmctl(shm_id, IPC_RMID, NULL);

实践

要求:一个进程创建共享内存,并写入字符串shared memory;而另一个进程则从共享内存中读取该字符串。

写入数据

创建共享内存,并写入一个字符串:

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
#include <sys/shm.h>
#include <stdlib.h>
#include <string.h>

int main()
{
key_t shmkey = ftok(".", 1);
int shmid = shmget(shmkey, 1024 * 1024, IPC_CREAT | 0666);
if (shmid == -1) {
exit(EXIT_FAILURE);
}

char *shm = (char *)shmat(shmid, 0, 0);
if (shm == NULL) {
exit(EXIT_FAILURE);
}

strcpy(shm, "shared memory");

int result = shmdt(shm);
if (result == -1) {
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}

创建共享内存并写入数据

其中,ipcs(ipc status)命令用于查看系统中的ipc状态,-m表示只输出共享内存的相关信息。

读取数据

读取共享内存中的字符串:

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
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
key_t shmkey = ftok(".", 1);
int shmid = shmget(shmkey, 1024 * 1024, 0666);
if (shmid == -1) {
exit(EXIT_FAILURE);
}

char *shm = (char *)shmat(shmid, 0, 0);
if (shm == NULL) {
exit(EXIT_FAILURE);
}

printf("%s\n", shm);
if (shmdt(shm) == -1) {
exit(EXIT_FAILURE);
}

if (shmctl(shmid, IPC_RMID, NULL) == -1) {
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}

读取共享内存


----------本文结束感谢您的阅读----------
坚持原创技术分享,您的支持将鼓励我继续创作!