在软件中,术语共享内存指可被多个进程存取的内存,一个进程是一段程序的单个运行实例。在这种情况下,共享内存被用作进程间的通讯。——WikiPedia
在Linux系统中,有多种C语言支持的共享内存使用方法,包括以下几种:
- 基于传统
SYS V的共享内存; - 基于
POSIX mmap文件映射实现共享内存; - 通过
memfd_create()和fd跨进程共享实现共享内存; - 多媒体、图形领域广泛使用的基于
dma-buf的共享内存。
CRIU是用于Linux操作系统的软件工具。使用此工具,可以冻结正在运行的应用程序,并将其作为文件集合检查点到持久性存储中。然后,人们可以使用这些文件从冻结点还原并运行应用程序。但不是所有程序都支持通过CRIU进行热迁移,例如使用了SYS V的C程序就不可以使用 CRIU 进行 进程热迁移。
这篇文章讨论如何使用CRIU迁移使用了共享内存的程序,主要讨论其中的前两种共享内存方法,最终介绍一种支持热迁移的C程序共享内存使用方法。
共享简单实现
System V ,曾经也被称为 AT&T System V,是Unix操作系统众多版本中的一支, SYS V 共享内存历史悠久、年代久远、API怪异,对应内核代码 linux/ipc/shm.c ,使用命令 ipcs 看到的就是这种内存; Posix 表示可移植操作系统接口(Portable Operating System Interface ,缩写为 POSIX ),POSIX标准定义了操作系统应该为应用程序提供的接口标准,是IEEE为要在各种 UNIX 操作系统上运行的软件而定义的一系列API标准的总称,其正式称呼为IEEE 1003,而国际标准名称为ISO/IEC 9945。
下面列举了两种共享内存的C程序使用方法。
(1)Sys V 共享内存
ipc_share_mem_write ,共享内存写入示例程序。
ipc_share_mem_read ,共享读取示例程序。
直接编译运行即可:
可以使用 free 命令查看执行前后共享内存空间的变化情况:
(2)POSIX 共享内存
ipc_share_mem_posix_write ,共享内存写入示例程序。
ipc_share_mem_posix_read ,共享读取示例程序。
直接编译运行即可:
之后可以在 /dev/shm/ 、 /run/shm 下面看到一个文件。
进程热迁移
上文简单提到了 criu 工具,本文的目标即迁移使用了共享内存的C程序,实测使用了 Sys V 共享内存的C程序无法迁移,报错如下:
使用POSIX mmap 文件映射实现共享内存的C程序可以使用 criu 实现进程热迁移,只需迁移共享内存文件及相关程序和文件即可实现本机和跨主机间的进程迁移,前提是内核、criu版本保持一致。迁移方法很简单,至于criu的安装,使用以下命令安装即可。
CLI 进行进程迁移
使用该方法可以将使用了共享内存的C程序冻结,之后恢复进程状态,Posix 共享内存的API略有不同,但使用方法类似,至于更进一步的探索,还需继续努力。
参考文献
- 宋宝华:世上最好的共享内存(Linux共享内存最透彻的一篇):https://blog.csdn.net/21cnbao/article/details/103470878
- Linux下的几种IPC方式及其C语言实现:https://www.cnblogs.com/acm-icpcer/p/8933628.html
- Linux Namespace : IPC:https://www.cnblogs.com/sparkdev/p/9400673.html
- IPC之Posix共享内存详解:https://blog.csdn.net/daiyudong2020/article/details/50500651
- UNIX System V - WikiPedia:https://zh.wikipedia.org/wiki/UNIXSystemV
- 共享内存 - WikiPedia:https://zh.wikipedia.org/wiki/共享内存
- What software is supported - criu wiki:https://criu.org/Whatsoftwareis_supported
- Shared memory - criu wiki:https://criu.org/index.php?title=Shared_memory