共享内存、Cgroups、命名空间
共享内存
对于共享内存是好是坏,我们不能妄下定论,不过学习一下总是好的。
不同进程之间内存空间是独立的,也就是说进程不能访问也不会干扰其他进程的内存。如果两个进程希望通过共享内存的方式通信呢?可以通过mmap()
系统调用实现。
Go实例
Go也实现了mmap()
函数支持共享内存,不过也是通过cgo来调用C实现的系统调用函数。Cgo是什么?它是Go调用C语言模块的功能,当然这种调用很可能是平台相关的,也就是无法保证在Windows也能正确运行。
具体代码参见Golang对共享内存的操作,有时间我们也愿意写一个更简单易懂的例子。
写时复制(Copy On Write)
一般我们运行程序都是Fork一个进程后马上执行Exec加载程序,而Fork的是否实际上用的是父进程的堆栈空间,Linux通过Copy On Write技术极大地减少了Fork的开销。
Copy On Write的含义是只有真正写的时候才把数据写到子进程的数据,Fork时只会把页表复制到子进程,这样父子进程都指向同一个物理内存页,只有再写子进程的时候才会把内存页的内容重新复制一份。
Cgroups
Cgroups全称Control Groups,是Linux内核用于资源隔离的技术。目前Cgroups可以控制CPU、内存、磁盘访问。
使用
Cgroups是在Linux 2.6.24合并到内核的,不过项目在不断完善,3.8内核加入了对内存的控制(kmemcg)。
要使用Cgroups非常简单,阅读前建议看sysadmincasts的视频,https://sysadmincasts.com/episodes/14-introduction-to-linux-control-groups-cgroups。
我们首先在文件系统创建Cgroups组,然后修改这个组的属性,启动进程时指定加入的Cgroups组,这样进程相当于在一个受限的资源内运行了。
实现
Cgroups的实现也不是特别复杂。有一个特殊的数据结构记录进程组的信息。
有人可能已经知道Cgroups是Docker容器技术的基础,另一项技术也是大名鼎鼎的Namespaces。
Namespaces简介
Linux Namespaces是资源隔离技术,在2.6.23合并到内核,而在3.12内核加入对用户空间的支持。
Namespaces是容器技术的基础,因为有了命名空间的隔离,才能限制容器之间的进程通信,像虚拟内存对于物理内存那样,开发者无需针对容器修改已有的代码。
使用Namespaces
阅读以下教程前建议看看,https://blog.jtlebi.fr/2013/12/22/introduction-to-linux-namespaces-part-1-uts/。
Linux内核提供了clone
系统调用,创建进程时使用clone
取代fork
即刻创建同一命名空间下的进程。
更多参数建议man clone
来学习。
下一节:Run是开源的脚本管理工具,官方网站http://runscripts.org,项目地址https://github.com/runscripts/run。