Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果计数值大于它所能容纳的值,CPU计时器如何工作?_C_Linux_Timer_Cpu Architecture - Fatal编程技术网

如果计数值大于它所能容纳的值,CPU计时器如何工作?

如果计数值大于它所能容纳的值,CPU计时器如何工作?,c,linux,timer,cpu-architecture,C,Linux,Timer,Cpu Architecture,如果我没有弄错的话,Csleep函数是使用CPU定时器的地方之一。 Linux将设置计时器并从调度程序中删除进程。计时器计数下降,一旦它点击0,它将中断CPU,操作系统将把进程重新添加到调度程序中。我说的对吗 如果是这样,那么如果计时器值大于计数器硬件可以处理的位数,会发生什么情况?假设计数器的最大位数为23位,我需要24位值(即我需要长时间睡眠) 编辑: 另外,如果我们同时有多个睡眠,超过CPU的计数器,该怎么办 睡眠功能是使用CPU定时器的地方之一 不是。Linux内核实现了一个。当您调用(

如果我没有弄错的话,C
sleep
函数是使用CPU定时器的地方之一。 Linux将设置计时器并从
调度程序中删除进程。计时器计数
下降
,一旦它点击
0
,它将中断CPU,操作系统将把进程重新添加到调度程序中。我说的对吗

如果是这样,那么如果计时器值大于计数器硬件可以处理的位数,会发生什么情况?假设计数器的最大位数为
23
位,我需要
24
位值(即我需要长时间
睡眠

编辑:

另外,如果我们同时有多个睡眠,超过CPU的计数器,该怎么办

睡眠功能是使用CPU定时器的地方之一

不是。Linux内核实现了一个。当您调用(Linux上的GNUC库使用
nanosleep()
来实现
sleep()
)时,您执行一个nanosleep;这会导致内核在所需的持续时间过去之前不调度该任务(通常是用户空间进程中的线程),或者使用该任务将信号发送到未安装SA_RESTART标志的用户空间信号处理程序(在这种情况下,系统调用返回
-EINTR

在微控制器上,比如Arduino或类似的,你可以用定时器实现睡眠

假设您有一个计时器功能,它可以从任何地方计数到
timer\u MAX
到零,即睡眠时间单位在1到
timer\u MAX
之间。如果您想长时间睡眠,可以在
TIMER\u MAX
时间间隔中进行:

/* Timer-based sleep function; returns the number of units slept,
   at most 'units'.  Can only sleep between 1 and TIMER_MAX, inclusive. */
static unsigned short  timer_sleep(unsigned short units);

void sleep(unsigned long duration)
{
    /* "long" sleep(s) */
    while (duration >= TIMER_MAX)
        duration -= timer_sleep(TIMER_MAX);

    /* "short" sleep(s) */
    while (duration > 0)
        duration -= timer_sleep(duration);
}

如果
timer\u sleep(u)
始终返回
u
,则可以用
timer\u sleep(duration)
替换后者while循环。如上所述,使用两个while循环,只要
timer\u sleep(u)
返回
u
或更少,睡眠就会工作。

现代PC有许多具有高级功能的硬件定时器,因此这种情况不太可能发生。但原则上,最简单的解决方案是让操作系统在软件中保留另一个计数器,跟踪硬件计数器需要翻转多少次才能恢复进程。每次硬件计数器达到0时,就会生成一个中断,中断处理程序会递减软件计数器,只有当软件计数器达到0时,才会发生任何进一步的情况。我明白了,我的另一个问题是,如果我们同时有多个
睡眠
,超过CPU的计数器,会怎么样?我猜这个软件会在这种情况下使用吗?就像你在现实生活中做的那样:你的挂钟每24小时一圈,但每次都会在日历上划出一页。因此,即使您唯一的硬件计时设备本身无法跟踪任意长度的时间,您也可以跟踪任意长度的时间。当然,每个睡眠进程都有一个计数器,当一个中断触发时,将其全部递减,然后查看哪些达到了0。这是一个非常简单的描述;实际的内核使用更复杂和高效的算法。只有一个中断。内核计算出哪个进程需要首先唤醒,计算需要多长时间才能唤醒,并将硬件计时器设置为在这段时间后启动。当它这样做时,它会调整每个进程所需的剩余时间(保留在软件中的一个值),唤醒任何准备好唤醒的进程,计算下一个进程需要唤醒多长时间,然后继续。但是,当时间到了,内核必须将程序重新添加到调度程序时,内核将如何得到通知?计时器没有这样做?@Dan:内核使用列表或树来维护任务。它让每个任务运行一段时间,然后检查它的列表/树,让哪个任务运行下一段时间。(这一部分只让任务运行一段时间,确实使用了计时器中断:这样即使用户空间处于紧密循环中,控制也会在时间片结束时返回到内核。在Linux中,这通常在0.01到0.001s之间,因此间隔非常短;对于Dyntick,它会一直变化)。这项检查的一部分是看是否有任务需要唤醒,因为它们已经睡了足够长的时间。如果CPU中只有很少数量的计时器硬件,它将如何运行多个程序?Dan:只需要一个硬件计时器,内核本身使用它来生成硬件中断(将执行返回内核)当下一个时间片结束时。软件计时器,如通过POSIX创建的计时器,只是内核数据结构,每个软件计时器的偏移量为全局时钟/计时器。当检查计时器是否将过期时,内核只需维护一个下一个过期的计时器列表或树,与内部全局时钟/计时器相关。