使用rlimit限制子进程的内存使用量,而不影响当前进程

I want to limit the memory usage of a child process using rlimit. Currently our code is as follows:

old_rlimit := get_rlimit()
set_rlimit(child_process_rlimit)
cmd.Start()
set_rlimit(old_rlimit)
cmd.Wait()

However, sometimes Golang runtime will report out of memory error at cmd.Start(). It seems that in cmd.Start() current process will allocate some memory, and if current memory usage is higher than child_process_rlimit, an error will be raised.

I want to know is there any way to limit the memory usage of child process without affecting current one?

You need to apply rlimit to the child process only rather than relying on rlimit inheritance. Your main blocker here is clearly spelled out in the setrlimit man page:

an unprivileged process may set only its soft limit to a value in the range from 0 up to the hard limit, and (irreversibly) lower its hard limit

The standard way to do this is through fork/exec, something along the lines of:

child_pid := fork()
if pid != 0 {
  // in child process
  setrlimit(...)
  execve(...)
}

If you don't want to do that, you still have a few options:

  • run as privileged user
  • cmd.Run a small wrapper (eg: bash ulimit -m ...) that calls the child process. note: -m is not honored by many systems.
  • call prlimit (linux-specific and no syscall wrapper. see this thread for details)