How a process running in Linux can determine for h

2019-09-11 00:31发布

问题:

Let's say a process is started at 12:00:00 and the only thing it does is to sleep for 120 seconds (sleep(120)). It should normally be woken up at 12:02:00. Imagine now that after 60 seconds the system suspends it (12:01:00) for 300 seconds (5 minutes). What happens is that at 12:06:00, the process is resumed and it immediately wakes because, as far I could understand, the sleep instruction uses the machine time to determine when it should wake up. But what I'm looking for is a solution where the process continues to sleep for the remaining 60 seconds.

A simple solution would be a "busy" sleep:

for (i = 0; i < 120; i++) sleep(1);

but I am looking for a solution like:

sleeping_time = 120;
do {
    start_time = current_time();
    sleep(sleeping_time);
    sleeping_time = sleeping_time - (current_time() - start_time - suspended_time()); 
} while ( sleeping_time > 0 );

In this case, the suspended_time() function would return the total time the process was suspended.

Thanks! Claudio

回答1:

the clock_gettime() function is available for the timing your interested in.

It can get elapsed time since the process started

It can get the actual time spent running the process (does not include elapsed time not running the process.)

Per the man page (trimmed to only discuss clock_gettime())

#include <time.h>
int clock_gettime(clockid_t clk_id, struct timespec *tp);

The tp argument is a timespec structure, as specified in :

       struct timespec {
           time_t   tv_sec;        /* seconds */
           long     tv_nsec;       /* nanoseconds */
       };

The clk_id argument is the identifier of the particular clock on which to act.

A clock may be system-wide and hence visible for all processes, or per-process if it measures time only within a single process.

  CLOCK_REALTIME
          System-wide  clock  that  measures real (i.e., wall-clock) time.
          Setting this clock requires appropriate privileges.  This  clock
          is  affected by discontinuous jumps in the system time (e.g., if
          the system administrator manually changes the clock), and by the
          incremental adjustments performed by adjtime(3) and NTP.

   CLOCK_REALTIME_COARSE (since Linux 2.6.32; Linux-specific)
          A  faster  but less precise version of CLOCK_REALTIME.  Use when
          you need very fast, but not fine-grained timestamps.

   CLOCK_MONOTONIC
          Clock that cannot be set and  represents  monotonic  time
          since some unspecified starting point.  This clock is not
          affected by discontinuous jumps in the system time (e.g.,
          if  the system administrator manually changes the clock),
          but is affected by the incremental adjustments  performed
          by adjtime(3) and NTP.

   CLOCK_MONOTONIC_COARSE (since Linux 2.6.32; Linux-specific)
          A  faster  but  less  precise version of CLOCK_MONOTONIC.
          Use when you need very fast, but not  fine-grained  time‐
          stamps.

   CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux-specific)
          Similar  to CLOCK_MONOTONIC, but provides access to a raw
          hardware-based time that is not subject  to  NTP  adjust‐
          ments  or  the  incremental adjustments performed by adj‐
          time(3).

   CLOCK_BOOTTIME (since Linux 2.6.39; Linux-specific)
          Identical to CLOCK_MONOTONIC, except it also includes any
          time  that the system is suspended.  This allows applica‐
          tions to get a suspend-aware monotonic clock without hav‐
          ing  to  deal  with  the complications of CLOCK_REALTIME,
          which may have discontinuities if  the  time  is  changed
          using settimeofday(2).

   CLOCK_PROCESS_CPUTIME_ID (since Linux 2.6.12)
          High-resolution per-process timer from the CPU.

   CLOCK_THREAD_CPUTIME_ID (since Linux 2.6.12)
          Thread-specific CPU-time clock.

RETURN VALUE
   clock_gettime()  returns 
       0 for success, 
       or 
       -1 for failure (in which case errno is set appropriately).

ERRORS
   EFAULT tp points outside the accessible address space.

   EINVAL The clk_id specified is not supported on this system.


标签: c linux