【问题标题】:is system(const char *command) lead to cpu sys 100%是 system(const char *command) 导致 cpu sys 100%
【发布时间】:2014-04-22 09:15:53
【问题描述】:

我创建了一个后台线程B,在B的func中,

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

我发现某个cpu(我的服务器有多个cpu核心)的sys是100%。 strace进度,我发现clone syscall消耗超过3秒,这几乎是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

所以我的问题是, 1. system('gzip -f text-file') 是否导致100% cpu sys? 2. 根本原因是什么

【问题讨论】:

  • 可能是因为clone会复制父进程的内存结构。 sys_clone -> do_fork -> copy_process -> dup_mm -> dup_mmap。在我的实验中,parent 的 rss 是 60G,大约 2000 个 mmap 条目。
  • 上面的猜测是对的。 copy_page_range消耗大部分时间,当进程的rss较大时,执行时间线性增加。

标签: linux-kernel system cpu-usage system-calls


【解决方案1】:

sys_clone 没有CLONE_MM 会根据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

2000 mmaps 中 60GB 进程的 VMA 计数很高,dup_mm 可能需要很多时间。

您想进行小型外部运行 (gzip),但对于此类大型程序来说,fork 并不是最佳解决方案。所有的 vma 副本都将通过 exec: http://landley.net/writing/memory-faq.txt 删除。

例如,fork/exec 组合会创建瞬态虚拟内存使用 尖峰,几乎立即再次消失而没有破坏 复制分叉页表中大多数页面的写入状态。因此 如果一个大进程分叉出一个小进程,巨大的物理内存 需求有可能发生(就过度使用而言),但从来没有 实现。

所以,你最好:

  • 检查 vfork+exec 对(又名 posix_spawn),这将暂停您的巨大进程一小段时间,直到孩子执行 exec 或 `exit)
  • 在执行所有 60GB 的 mmap 之前创建单独的辅助进程;使用管道/套接字/ipc/任何东西与它通信。辅助进程很小,大部分时间都在 ipc 上休眠。当您需要gzip 时,您只需要求助手运行它。
  • 或将压缩集成到您的程序中。 Gzip 和 bzip2 都有很好的库,zliblibbz2,并且在 boost 中有包装器。

【讨论】:

    猜你喜欢
    • 2014-08-29
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2019-01-14
    • 1970-01-01
    • 1970-01-01
    • 2013-03-14
    • 2019-11-04
    相关资源
    最近更新 更多