Chinaunix首页 | 论坛 | 博客
  • 博客访问: 556678
  • 博文数量: 92
  • 博客积分: 2511
  • 博客等级: 少校
  • 技术积分: 932
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-19 10:10
文章分类
文章存档

2011年(6)

2010年(27)

2009年(37)

2008年(22)

我的朋友

分类: LINUX

2010-01-28 22:52:24

POSIX
clocks family provides the most advanced sleep interface:
#include
int clock_nanosleep (clockid_t clock_id,
                     int flags,
                     const struct timespec *req,
                     struct timespec *rem);
clock_nanosleep( ) behaves similarly to nanosleep( ). In fact, this call:
ret = nanosleep (&req, &rem);
is the same as this call:
ret = clock_nanosleep (CLOCK_REALTIME, 0, &req, &rem);
The difference lies in the clock_id and flags parameters. The former specifies the
time source to measure against. Most time sources are valid, although you cannot
specify the CPUclock of the invoking process (e.g., CLOCK_PROCESS_CPUTIME_ID);
doing so would make no sense because the call suspends execution of the process,
and thus the process time stops increasing.
What time source you specify depends on your program’s goals for sleeping. If you
are sleeping until some absolute time value, CLOCK_REALTIME may make the most
sense. If you are sleeping for a relative amount of time, CLOCK_MONOTONIC definitely is
the ideal time source.
The flags parameter is either TIMER_ABSTIME or 0.Ifitis TIMER_ABSTIME, the value
specified by req is treated as absolute, and not relative. This solves a potential race con-
dition. To explain the value of this parameter, assume that a process, at time T0, wants
to sleep until time T1.At T0, the process calls clock_gettime( ) to obtain the current time
(T0). It then subtracts T0 from T1, obtaining Y, which it passes to clock_nanosleep( ).
Some amount of time, however, will have passed between the moment at which the
time was obtained, and the moment at which the process goes to sleep. Worse, what if
the process was scheduled off the processor, incurred a page fault, or something simi-
lar? There is always a potential race condition in between obtaining the current time,
calculating the time differential, and actually sleeping.
The TIMER_ABSTIME flag nullifies the race by allowing a process to directly s
The kernel suspends the process until the specified time source reaches
specified time source’s current time already exceeds T1, the call returns imm
Let’s look at both relative and absolute sleeping. The following example slee
seconds:
struct timespec ts = { .tv_sec = 1, .tv_nsec = 500000000 };
int ret;
ret = clock_nanosleep (CLOCK_MONOTONIC, 0, &ts, NULL);
if (ret)
        perror ("clock_nanosleep");
Conversely, the following example sleeps until an absolute value of time—
exactly one second from what the clock_gettime( ) call returns for the CLOCK_
time source—is reached:
struct timespec ts;
int ret;
/* we want to sleep until one second from NOW */
ret = clock_gettime (CLOCK_MONOTONIC, &ts);
if (ret) {
        perror ("clock_gettime");
        return;
}
ts.tv_sec += 1;
printf ("We want to sleep until sec=%ld nsec=%ld\n",
        ts.tv_sec, ts.tv_nsec);
ret = clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME,
                       &ts, NULL);
if (ret)
        perror ("clock_nanosleep");
Most programs need only a relative sleep because their sleep needs are not very strict.
Some real-time processes, however, have very exact timing requirements, and need
the absolute sleep to avoid the danger of a potentially devastating race condition.
更详细的可以参考man page或者移步这里
Portable way:
#include
int select (int n,
            fd_set *readfds,
            fd_set *writefds,
            fd_set *exceptfds,
            struct timeval *timeout);
As mentioned in that chapter, select( ) provides a portable way to sleep with sub-
second resolution. For a long time, portable Unix programs were stuck with sleep( )
for their naptime needs: usleep( ) was not widely available, and nanosleep( ) was as
of yet unwritten. Developers discovered that passing select( ) 0 for n, NULL for all
three of the fd_set pointers, and the desired sleep duration for timeout resulted in a
portable and efficient way to put processes to sleep:
struct timeval tv = { .tv_sec = 0,
                      .tv_usec = 757 };
/* sleep for 757 us */
select (0, NULL, NULL, NULL, &tv);
If portability to older Unix systems is a concern, using select( ) may be your best bet.
阅读(901) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~