Question

I create one background thread B,and in func of B,

void func()
{
  system('gzip -f text-file'); // size of text-file is 100M
  xxx
}

I found sometime the sys of one cpu(my server has more than one cpu core) is 100%. strace the progress, I found clone syscall consume more than 3 seconds, which is almost execution time of gzip.

**17:46:04.545159** clone(child_stack=0, flags=CLONE_PARENT_SETTID|SIGCHLD, parent_tidptr=0x418dba38) = 39169
**17:46:07.432385** wait4(39169, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 39169

so my question is, 1. is system('gzip -f text-file') lead to 100% cpu sys ? 2. what is the root cause

Was it helpful?

Solution

sys_clone without CLONE_MM does full copy of virtual memory mapping from parent process into child process, according to https://www.kernel.org/doc/gorman/html/understand/understand021.html

343      Allocate a new mm
348-350  Copy the parent mm and initialise the process specific mm fields with init_mm()
352-353  Initialise the MMU context for architectures that do not automatically manage their MMU
355-357  Call dup_mmap() which is responsible for copying all the VMAs regions in use by the parent process

VMA count for process with 60GB in 2000 mmaps is high, and dup_mm may take lot of time.

You want to do small external run (gzip), but the fork is not best solution for such large programs. All copies of vma will be trashed by doing exec: http://landley.net/writing/memory-faq.txt

For example, the fork/exec combo creates transient virtual memory usage spikes, which go away again almost immediately without ever breaking the copy on write status of most of the pages in the forked page tables. Thus if a large process forks off a smaller process, enormous physical memory demands threaten to happen (as far as overcommit is concerned), but never materialize.

So, it can be better for you to:

  • check vfork+exec pair (aka posix_spawn), which will suspend your huge process for small time, until child will do exec or `exit)
  • create separate helper process before doing all the 60GB of mmaps; communicate with it using pipes/sockets/ipc/anything. Helper process is small and will sleep most time on ipc. When you needs gzip, you just asks helper to run it.
  • or integrate compression into your program. Gzip and bzip2 both has good libraries, zlib and libbz2, and there are wrappers in boost.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top