ppcc800330 发表于 2016-03-28 11:09

请教posix定时器的精度问题

请问下,如果我在用户层使用posix定时器,这个定时器接口的精度是微妙级别的,
但Linux系统内核的tick一般都是毫秒级别的,这意味这调度是毫秒级别的,那么
理论上用户空间的定时器是达不到微妙级别的吧,请问我的理解对吗?如果想在
用户空间达到微妙级别的精度有什么办法呢?

nswcfd 发表于 2016-03-29 11:59

也不绝对,关键看系统里有哪些clocksource。

比如HPET,https://en.wikipedia.org/wiki/High_Precision_Event_Timer

ppcc800330 发表于 2016-03-29 21:25

我的意识是就算底层的时钟源再精准(比如HEPT),但时钟中断后需要通知进程处理,但进程的调度是tick(毫秒)级别的,受限于tick调度,这样不管底层的时钟源再精准,
进程的timer都达不到微妙级别。

_nosay 发表于 2016-03-29 21:52

本帖最后由 _nosay 于 2016-03-29 21:57 编辑

回复 3# ppcc800330

哦,是说用户态实现的定时器呀。

polejo 发表于 2016-03-30 10:22

usleep和msleep,我记得都是通过内核的 nanosleep 来实现的。

最精确的:直接去读cpu的counter寄存器,跟cpu的时钟频率做换算。

nswcfd 发表于 2016-03-30 11:01

本帖最后由 nswcfd 于 2016-03-30 11:02 编辑

仅供参考。

两台机器上man nanosleep的区别。

版本1,Linux 2.6.9 @ 2004-10-24,注意BUGS部分。
NAME
       nanosleep - pause execution for a specified time

SYNOPSIS
       #define _POSIX_C_SOURCE 199309 #include <time.h>

       int nanosleep(const struct timespec *req, struct timespec *rem);
BUGS
       The current implementation of nanosleep() is based on the normal kernel timer mechanism, which has a resolution of 1/HZ s (see time(7)).Therefore, nanosleep() pauses always forat
       leastthe specified time, however it can take up to 10 ms longer than specified until the process becomes runnable again. For the same reason, the value returned in case of a deliv-
       ered signal in *rem is usually rounded to the next larger multiple of 1/HZ s.

   Old behaviour
       In order to support applications requiring much more precise pauses (e.g., in order to control some time-critical hardware), nanosleep() would handle pauses of upto2 msbybusy
       waitingwithmicrosecondprecision when called from a process scheduled under a real-time policy like SCHED_FIFO or SCHED_RR.This special extension was removed in kernel 2.5.39,
       hence is still present in current 2.4 kernels, but not in 2.6 kernels.

       In Linux 2.4, if nanosleep() is stopped by a signal (e.g., SIGTSTP), then the call fails with the error EINTR after the process is resumed by a SIGCONT signal.If the system call is
       subsequently restarted, then the time that the process spent in the stopped state is not counted against the sleep interval.

CONFORMING TO
       POSIX.1-2001.

SEE ALSO
       sched_setscheduler(2), timer_create(2), sleep(3), usleep(3)

Linux 2.6.9                     2004-10-24                      NANOSLEEP(2)

版本2,2009-01-19,3.22,没有前面的BUG描述(受限于timer精度)。
NAME
       nanosleep - high-resolution sleep

SYNOPSIS
       #include <time.h>

       int nanosleep(const struct timespec *req, struct timespec *rem);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       nanosleep(): _POSIX_C_SOURCE >= 199309L

CONFORMING TO
       POSIX.1-2001.

NOTES
       If the interval specified in req is not an exact multiple of the granularity underlying clock (see time(7)), then the interval will be rounded up to the next multiple.Furthermore, afterthesleepcom-
       pletes, there may still be a delay before the CPU becomes free to once again execute the calling thread.

       Thefact that nanosleep() sleeps for a relative interval can be problematic if the call is repeatedly restarted after being interrupted by signals, since the time between the interruptions and restarts of
       the call will lead to drift in the time when the sleep finally completes.This problem can be avoided by using clock_nanosleep(2) with an absolute time value.

       POSIX.1 specifies that nanosleep() should measure time against the CLOCK_REALTIME clock.However, Linux measures the time using the CLOCK_MONOTONIC clock.This probably does not matter, since the POSIX.1
       specification for clock_settime() says that discontinuous changes in CLOCK_REALTIME should not affect nanosleep():

            SettingthevalueoftheCLOCK_REALTIMEclockviaclock_settime()shallhaveno effect on threads that are blocked waiting for a relative time service based upon this clock, including the
            nanosleep() function; ...Consequently, these time services shall expire when the requested relative interval elapses, independently of the new or old value of the clock.

   Old behavior
       In order to support applications requiring much more precise pauses (e.g., in order to control some time-critical hardware), nanosleep() would handle pauses of up to 2 ms by busy waitingwithmicrosecond
       precisionwhen called from a thread scheduled under a real-time policy like SCHED_FIFO or SCHED_RR.This special extension was removed in kernel 2.5.39, hence is still present in current 2.4 kernels, but
       not in 2.6 kernels.

BUGS
       In Linux 2.4, if nanosleep() is stopped by a signal (e.g., SIGTSTP), then the call fails with the error EINTR after the thread is resumed by a SIGCONT signal.If the system call is subsequently restarted,
       then the time that the thread spent in the stopped state is not counted against the sleep interval.

SEE ALSO
       clock_nanosleep(2), sched_setscheduler(2), sleep(3), timer_create(2), usleep(3), time(7)

COLOPHON
       This page is part of release 3.22 of the Linux man-pages project.A description of the project, and information about reporting bugs, can be found at http://www.kernel.org/doc/man-pages/.

Linux                           2009-01-19                      NANOSLEEP(2)

nswcfd 发表于 2016-03-30 11:20

PS,参考2,http://stackoverflow.com/questions/13369087/linux-high-resolution-timer-in-user-space

archer239915 发表于 2016-04-07 23:37

用户是可以达到ns级的定时器精度的。而且你说的定时器受限于ms级的tick精度也是不对的。内核开了高精度定时器时,tick的精度和定时器的精度完全没有关系。
页: [1]
查看完整版本: 请教posix定时器的精度问题