> For the complete documentation index, see [llms.txt](https://richardweiyang-2.gitbook.io/kernel-exploring/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://richardweiyang-2.gitbook.io/kernel-exploring/00-index/01-control_cpu_mem_by_cgroup.md).

# 使用cgroup控制进程cpu和内存

刚开始接触cgroup时，第一个任务就是用cgroup限制cpu/mem的使用。可能这也是大多数人接触到cgroup时，需要做的任务。

## 使用cgroup限制进程能运行的cpu

在这个例子中，我们探寻一下如何用cgroup限制进程能够在哪些cpu上调度。在云计算场景中，我们通常会用这个功能来隔离不同的用户/业务，保证对应资源的使用情况。

这个过程分为两步：

* 创建一个限制了cpu调度的cgroup
* 将指定进程加入到该cgroup中

### 新建限制cpu的cgroup

```
mkdir /sys/fs/cgroup/cpuset/test
echo "0-1" > /sys/fs/cgroup/cpuset/test/cpuset.cpus
```

这样就创建了一个cgroup，并且限制了该cgroup中的进程只能运行在0-1号cpu上。

### 将指定进程加入cgoup

```
echo $pid > /sys/fs/cgroup/cpuset/test/cgroup.procs
```

这么看坑你还是有点空，我们来看一个实际的例子

### 完整例子

```
mkdir /sys/fs/cgroup/cpuset/test

echo "0-1" > /sys/fs/cgroup/cpuset/test/cpuset.cpus
echo 0 > /sys/fs/cgroup/cpuset/test/cpuset.mems

# echo current shell process number to cgroup.procs
# so all child will inherit this attribute
echo $$ > /sys/fs/cgroup/cpuset/test/cgroup.procs

# stress on 4 cpus
$ stress -c 4

# while only 2 cpu is working
$ top
```

正常情况下，stress -c 4会使用4块cpu。但是因为将测试进程放进了cgroup，所以只有两个cpu在实际使用。

## 使用cgroup限制内存使用

在这个例子中，我们探寻一下如何用cgroup限制进程能够使用的内存。在云计算场景中，我们通常会用这个功能来限制用户/业务的内存，保证对应资源的使用情况，避免有恶意用户/业务抢占资源。

这个过程分为两步：

* 创建一个限制内存使用的cgroup
* 将指定进程加入到该cgroup中

### 创建限制内存使用的cgroup

```
mkdir /sys/fs/cgroup/memory/test

# limit 4M
echo 4M > /sys/fs/cgroup/memory/test/memory.limit_in_bytes
```

### 将指定进程加入cgoup

```
echo $pid > /sys/fs/cgroup/cpuset/test/cgroup.procs
```

这一步完全一样。。。

### 完整例子

以例服人

```
# create a cgroup with memory limitation
mkdir /sys/fs/cgroup/memory/test
# limit 4M
echo 4M > /sys/fs/cgroup/memory/test/memory.limit_in_bytes
# disable swap, otherwise it will use swap to get more "memory"
echo 0 > /sys/fs/cgroup/cpuset/rabbit/memory.swappiness

# put ourself into this cgroup
echo $$ > /sys/fs/cgroup/cpuset/rabbit/cgroup.procs

# prepare a program eats memory
cat eat_mem.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define MB (1024 * 1024)

int main(int argc, char *argv[])
{
    char *p;
    int i = 0;
    while(1) {
        p = (char *)malloc(MB);
        memset(p, 0, MB);
        printf("%dM memory allocated\n", ++i);
        sleep(1);
    }

    return 0;
}

# run to trigger oom
./eat_mem
```

上面的例子中，有一点值得注意的是这个cgroup的swap被关掉了。否则的话，当进程内存不够，内核会将进程的内存交换到磁盘上。虽然进程的内存实际上是被限制了，但是无法触发oom观察到实验结果。

好了，希望上面两个例子能够让你亲眼看到cgroup的操作和效果。接下来我们就开始探索其中的奥秘了～
