在 Linux 上,“正常运行时间”从什么时候开始计算?

fed*_*qui 56 linux uptime linux-kernel

我的电脑说:

$ uptime
 10:20:35 up  1:46,  3 users,  load average: 0,03, 0,10, 0,13
Run Code Online (Sandbox Code Playgroud)

如果我检查,last我会看到:

reboot   system boot  3.19.0-51-generi Tue Apr 12 08:34 - 10:20  (01:45)    
Run Code Online (Sandbox Code Playgroud)

然后我检查:

$ ls -l /var/log/boot.log 
-rw-r--r-- 1 root root 4734 Apr 12 08:34 boot.log
Run Code Online (Sandbox Code Playgroud)

然后我在/var/log/syslog今天的第一行看到:

Apr 12 08:34:39 PC... rsyslogd: [origin software="rsyslogd" swVersion="7.4.4" x-pid="820" x-info="http://www.rsyslog.com"] start
Run Code Online (Sandbox Code Playgroud)

所以一切似乎都集中在8:34我的机器启动的时候。

但是,我想知道:确切的时间uptime使用是什么?是uptime启动并检查某个文件的进程还是硬件上的某个进程?

我正在运行 Ubuntu 14.04。

cha*_*aos 84

在我的系统上,它从/proc/uptime以下位置获得正常运行时间:

$ strace -eopen uptime
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/libproc-3.2.8.so", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/proc/version", O_RDONLY)         = 3
open("/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 3
open("/etc/localtime", O_RDONLY|O_CLOEXEC) = 3
open("/proc/uptime", O_RDONLY)          = 3
open("/var/run/utmp", O_RDONLY|O_CLOEXEC) = 4
open("/proc/loadavg", O_RDONLY)         = 4
 10:52:38 up 3 days, 23:38,  4 users,  load average: 0.00, 0.02, 0.05
Run Code Online (Sandbox Code Playgroud)

proc 联机帮助页

   /proc/uptime
          This file contains two numbers: the uptime of the system
          (seconds), and the amount of time spent in idle process
          (seconds).
Run Code Online (Sandbox Code Playgroud)

proc 文件系统包含一组伪文件。这些不是真正的文件,它们只是看起来像文件,但它们包含由内核直接提供的值。每次读取文件时,例如/proc/uptime,其内容都会即时重新生成。proc 文件系统是内核的接口。


在文件的Linux内核源代码fs/proc/uptime.c第49行,你会看到一个函数调用:

proc_create("uptime", 0, NULL, &uptime_proc_fops);
Run Code Online (Sandbox Code Playgroud)

这将创建一个名为的proc 文件系统条目uptime(procfs 通常安装在 下/proc),并将一个函数与其关联,该函数定义了对该伪文件的有效文件操作以及与其关联的函数。在正常运行时间的情况下,它只是read()open()操作。但是,如果您追溯这些功能,您最终会在此处计算正常运行时间。


在内部,有一个计时器中断,它会定期更新系统正常运行时间(除其他值外)。timer-interupt 滴答的间隔由 preprocessor-macroHZ定义,其确切值在内核配置文件中定义并在编译时应用。

空闲时间和 CPU 周期数,结合频率HZ(每秒周期数),可以计算出自上次启动以来的(秒)数。


解决您的问题:“正常运行时间”从什么时候开始计算?

由于正常运行时间是一个内核内部值,它在每个周期都会增加,因此它在内核初始化时开始计数。也就是说,当第一个周期结束时。甚至在安装任何东西之前,直接在引导加载程序将控制权交给内核映像之后。

  • @Prem 这是内核初始化的一部分。在调度程序初始化之前,定时器中断将被注册。定时器中断调用调度程序代码的第一次迭代(仅通过函数调用)。如果你有兴趣,这是一个很好的阅读:https://github.com/0xAX/linux-insides/blob/master/Initialization/README.md (3认同)
  • +1,@chaos,说​​在安装定时器中断处理程序时启动正常运行时间计数器会更准确吗?内核是否配置了这个处理程序? (2认同)

Inc*_*der 10

据我所知,uptime用于/proc/uptime计算系统正常运行时间。你可以在源代码uptime.c 中更清楚地看到它

  FILE *fp;

  fp = fopen ("/proc/uptime", "r");
  if (fp != NULL)
    {
      char buf[BUFSIZ];
      char *b = fgets (buf, BUFSIZ, fp);
      if (b == buf)
        {
          char *end_ptr;
          double upsecs = c_strtod (buf, &end_ptr);
          if (buf != end_ptr)
            uptime = (0 <= upsecs && upsecs < TYPE_MAXIMUM (time_t)
                      ? upsecs : -1);
        }

      fclose (fp);
    }
Run Code Online (Sandbox Code Playgroud)

  • 这不是真的。看看上面链接中的源代码。 (2认同)

sch*_*ily 6

在标准 UNIX 系统上(基于原始来源 *), uptime读取/var/adm/utmpx并检查最后一次重启条目。

换句话说:这是检索您也获得的日期who -b,然后计算从那时起的时间。

*)uptimew程序的链接,由 BSD 于 1980 年左右引入。

  • 我认为 _standard_,你的意思是 _traditional_。Unix 标准没有指定 `uptime` 命令,更不用说它应该如何实现了。AFAICT,OS/X 也没有 /var/adm/utmpx。并且一些基于 Linux 的系统已获得 Unix 合规性认证。 (5认同)
  • 在这种情况下,您应该提及您使用的操作系统类型。 (3认同)