歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

nanosleep和usleep和sleep和alarm

用戶程序中的睡眠:
    sleep()
    usleep()
    nanosleep()

    sleep()和nanosleep()都是使進程睡眠一段時間後被喚醒,但是二者的實現完全不同。
    Linux中並沒有提供系統調用sleep(),sleep()是在庫函數中實現的,它是通過調用alarm()來設定報警時間,調用sigsuspend()將進程掛起在信號SIGALARM上,sleep()只能精確到秒級上。

    nanosleep()則是Linux中的系統調用,它是使用定時器來實現的,該調用使調用進程睡眠,並往定時器隊列上加入一個timer_list型定時器,time_list結構裡包括喚醒時間以及喚醒後執行的函數,通過nanosleep()加入的定時器的執行函數僅僅完成喚醒當前進程的功能。系統通過一定的機制定時檢查這些隊列(比如通過系統調用陷入核心後,從核心返回用戶態前,要檢查當前進程的時間片是否已經耗盡,如果是則調用schedule()函數重新調度,該函數中就會檢查定時器隊列,另外慢中斷返回前也會做此檢查),如果定時時間已超過,則執行定時器指定的函數喚醒調用進程。當然,由於系統時間片可能丟失,所以nanosleep()精度也不是很高。

    alarm()也是通過定時器實現的,但是其精度只精確到秒級,另外,它設置的定時器執行函數是在指定時間向當前進程發送SIGALRM信號。




-------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sched.h>
#define COUNT 1000
#define MILLION 1000000L

int main(void)
{
    int i;
    struct timespec slptm;
    long   tdif;
    struct timeval tend, tstart;

    slptm.tv_sec = 0;
    slptm.tv_nsec = 1000;      //1000 ns = 1 us

    //struct sched_param param;   
    //param.sched_priority = 0;
    //sched_setscheduler(getpid(), SCHED_FIFO, &param);

    if (gettimeofday(&tstart, NULL) == -1) {
        fprintf(stderr, "Failed to get start time\n");
        return 1;
    }
    for (i = 0; i < COUNT; i++) {
        if (nanosleep(&slptm, NULL) == -1) {
            perror("Failed to nanosleep");
            return 1;
        }
    }
    if (gettimeofday(&tend, NULL) == -1) {
        fprintf(stderr, "Failed to get end time\n");
        return 1;
    }
    tdif = MILLION * (tend.tv_sec - tstart.tv_sec) + (tend.tv_usec - tstart.tv_usec);
    printf("nanosleep() time is %ld us\n", tdif/COUNT);
    return 0;
}



HZ                                 250HZ
時鐘中斷的時間間隔:                   4 ms   (1000ms/250)
----------------------------------------
nanosleep() time is 4019 us        (4.019 ms)
說明nanosleep的睡眠定時器依賴於時鐘中斷



HZ                                 1000HZ
時鐘中斷的時間間隔:                   1 ms
----------------------------------------
nanosleep() time is 12 us
注: 最小睡眠時間為1 us
Copyright © Linux教程網 All Rights Reserved