1. 程式人生 > >Linux訊號實踐(5) --時間與定時器

Linux訊號實踐(5) --時間與定時器

三種不同精度的睡眠

1.sleep

#include <unistd.h>
unsigned int sleep(unsigned int seconds);

RETURN VALUE

   Zero if the requested time has elapsed, or the number of seconds left to  sleep,  

if  the call was interrupted by a signal handler.

//示例
int sleepTime = 5;
do
{
    sleepTime = sleep(sleepTime);
}
while (sleepTime > 0);

2.usleep(以微秒為單位)

int usleep(useconds_t usec);

The  type useconds_t is an unsigned integer type capable of holding integers in the range [0,1000000]. 

Programs will be more portable if they never mention this type  explicitly.

3.nanosleep(以納秒為單位)

#include <time.h>
int nanosleep(const struct timespec *req, struct timespec *rem);

req指定睡眠的時間, rem返回剩餘的睡眠時間

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

三種時間結構

time_t
struct timeval {
	long    tv_sec;         /* seconds */
	long    tv_usec;        /* microseconds 微秒*/
};
struct timespec {
	time_t tv_sec;        /* seconds */
	long   tv_nsec;       /* nanoseconds */
};

setitimer

#include <sys/time.h>
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));

setitimer()比alarm功能強大,支援3種類型的定時器

引數

  第一個引數which指定定時器型別

  第二個引數是請求的時間

  第三個引數是定時器原來所關聯的值

struct itimerval
{
    struct timeval it_interval; /* next value : 產生訊號的間隔時間*/
    struct timeval it_value;    /* current value : 第一次產生訊號的時間*/
};
struct timeval
{
    time_t      tv_sec;         /* seconds: 秒 */
    suseconds_t tv_usec;        /* microseconds: 微秒 */
};

which值

  ITIMER_REAL: 經過指定的時間後,核心將傳送SIGALRM訊號給本程序 (用的較多)

  ITIMER_VIRTUAL : 程式在使用者空間執行指定的時間後,核心將傳送SIGVTALRM訊號給本程序 

  ITIMER_PROF : 程序在核心空間中執行時,時間計數會減少,通常與ITIMER_VIRTUAL共用,代表程序在使用者空間與核心空間中執行指定時間後,核心將傳送SIGPROF訊號給本程序。

/**示例1:
1.在啟動程序的5秒之後產生訊號
2.然後每隔1秒產生一次訊號
**/
int main()
{
    if (signal(SIGALRM, signalAction) == SIG_ERR)
        err_exit("signal error");

    struct itimerval it;
    struct timeval it_interval = {1, 0};
    struct timeval it_value = {5, 0};
    it.it_interval = it_interval;
    it.it_value = it_value;
    if (setitimer(ITIMER_REAL, &it, NULL) == -1)
        err_exit("setitimer error");

    while (true)
        pause();
}
/**示例2:
獲取itimerval 結構體
**/
int main()
{
    struct itimerval it;
    struct timeval it_interval = {1, 0};
    struct timeval it_value = {5, 0};
    it.it_interval = it_interval;
    it.it_value = it_value;
    if (setitimer(ITIMER_REAL, &it, NULL) == -1)
        err_exit("setitimer error");

    for (int i = 0; i < 100000; ++i)
        ;

    struct itimerval oldIt;

//    if (setitimer(ITIMER_REAL, &it, &oldIt) == -1)
//        err_exit("setitimer error");
    // 在不重新設定時鐘的情況下獲取剩餘時間
    if (getitimer(ITIMER_REAL, &oldIt) == -1)
        err_exit("getitimer error");

    cout << oldIt.it_interval.tv_sec << ' ' << oldIt.it_interval.tv_usec
         << ' ' << oldIt.it_value.tv_sec << ' ' << oldIt.it_value.tv_usec << endl;
}

附:秒-微秒-納秒的轉換

  S(秒)、ms(毫秒)、μs(微秒)、ns(納秒),其中:1s=1000ms,1 ms=1000μs,1μs=1000ns