IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

ulimit -t 引起的kill血案

Erlang非业余研究 2012-09-30 15:17:19 累计浏览 3,927 次
本机暂存

    今天在内核群里印风同学问了个问题:

    某台机器的ulimit -t 不知道为啥是300, 这是不是意味着程序占用CPU 300秒后会收到SIGKILL ?

     我用gdb跑mysqld 跑了一会,收到SIGKILL信号,没有配置cgroup,也没啥后台脚本,看了下,就ulimit -t 比较诡异,其他机器都是unlimited。

    简单的man ulimit下手册说:

     -t The maximum amount of cpu time in seconds

    貌似限制的是CPU最大执行时间,以秒为单位。

     为了验证上面的说法,我特地设计了以下的场景:我们首先运行一个死循环程序消耗CPU时间,同时把进程的最大CPU消耗时间设定在180秒,期待在这个时间点进程会被杀掉。

     以下是验证过程:

$ uname -r
2.6.32-131.21.1.tb477.el6.x86_64
$ ulimit -t 180
$ ulimit -t
180
$ cat busy.c
int main(int argc, char *argv[]) {
  for(;;);
  return 0;
}
$ gcc busy.c 
$ time ./a.out 
Killed

real	3m0.029s
user	2m59.966s
sys	0m0.007s

    从现象来看,3分钟后我们的busy进程确实被杀了,dmesg也没说什么原因被杀。

     不过不怕我早有准备,提早在运行的同时在另外一个终端开了个stap脚本来确定到底谁杀死了我们的进程:

$ cat sigkill.stp
probe signal.send{
  if(sig_name == "SIGKILL")
    printf("%s was sent to %s (pid:%d) by %s uid :%d\\n", sig_name, pid_name , sig_pid, execname(), uid())
}

$ sudo stap sigkill.stp
SIGKILL was sent to a.out (pid:23700) by a.out uid :50920

    我们可以看的很清楚是./a.out给自己发的kill信号,属于自杀非他杀,行为有点意思吧!

    木名同学找了下内核代码确认了以上行为:

     ./kernel/posix-cpu-timers.c:1139

           if (psecs >= sig->rlim[RLIMIT_CPU].rlim_max) {
                        /*                                                                                                                                               
                         * At the hard limit, we just die.                                                                                                               
                         * No need to calculate anything else now.                                                                                                       
                         */
                        __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
                        return;
                }
                if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
                        /*                                                                                                                                               
                         * At the soft limit, send a SIGXCPU every second.                                                                                               
                         */
                        __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk);
                        if (sig->rlim[RLIMIT_CPU].rlim_cur
                            < sig->rlim[RLIMIT_CPU].rlim_max) {
                                sig->rlim[RLIMIT_CPU].rlim_cur++;
			}
                }

    内核的代码解释的很清楚,超过硬CPU限制就简单粗暴的让进程被自杀了。之前我还说内核不大可能这么狠,没想到。。。

     小结:多看代码,少猜测。

同分类推荐文章

  1. 从零重建 macOS 开发机:可复现的环境初始化流程 (2026-06-14 20:36:00)
  2. 百度物理网络监控工具开源第二弹:毫秒级监控工具 baize,让你的网络问题无处遁形 (2026-06-11 08:10:28)
  3. How to Set Up Homebrew Tap for Private CLI Tools: A Complete Guide (2026-05-27 02:13:03)

查看更多 DevOps 文章 →

建议继续学习

  1. 用Hyer来进行网站的抓取 (累计阅读 158,250)
  2. MySQL数据库在实际应用一些方面的介绍 (累计阅读 36,397)
  3. WordPress插件开发 -- 在插件使用数据库存储数据 (累计阅读 29,164)
  4. Mysql监控指南 (累计阅读 21,350)
  5. 由浅入深探究mysql索引结构原理、性能分析与优化 (累计阅读 16,522)
  6. Linux如何统计进程的CPU利用率 (累计阅读 16,307)
  7. 调试工具之GDB (累计阅读 14,829)
  8. 我的 RHCA 之路 (累计阅读 14,012)
  9. Linux内存点滴 用户进程内存空间 (累计阅读 13,228)
  10. 给程序员新手的一些建议 (累计阅读 13,088)