用戶程序中的睡眠:
sleep()
usleep()
nanosleep()
sleep()和nanosleep()都是使進程睡眠一段時間后被喚醒,但是二者的實現(xiàn)完全不同。
Linux中并沒有提供系統(tǒng)調(diào)用sleep(),sleep()是在庫函數(shù)中實現(xiàn)的,它是通過調(diào)用alarm()來設(shè)定報警時間,調(diào)用sigsuspend()將進程掛起在信號SIGALARM上,sleep()只能精確到秒級上。
nanosleep()則是Linux中的系統(tǒng)調(diào)用,它是使用定時器來實現(xiàn)的,該調(diào)用使調(diào)用進程睡眠,并往定時器隊列上加入一個timer_list型定時器,time_list結(jié)構(gòu)里包括喚醒時間以及喚醒后執(zhí)行的函數(shù),通過nanosleep()加入的定時器的執(zhí)行函數(shù)僅僅完成喚醒當(dāng)前進程的功能。系統(tǒng)通過一定的機制定時檢查這些隊列(比如通過系統(tǒng)調(diào)用陷入核心后,從核心返回用戶態(tài)前,要檢查當(dāng)前進程的時間片是否已經(jīng)耗盡,如果是則調(diào)用schedule()函數(shù)重新調(diào)度,該函數(shù)中就會檢查定時器隊列,另外慢中斷返回前也會做此檢查),如果定時時間已超過,則執(zhí)行定時器指定的函數(shù)喚醒調(diào)用進程。當(dāng)然,由于系統(tǒng)時間片可能丟失,所以nanosleep()精度也不是很高。
alarm()也是通過定時器實現(xiàn)的,但是其精度只精確到秒級,另外,它設(shè)置的定時器執(zhí)行函數(shù)是在指定時間向當(dāng)前進程發(fā)送SIGALRM信號。
#include stdio.h>
#include stdlib.h>
#include unistd.h>
#include sys/time.h>
#include sched.h>
#define COUNT 1000
#define MILLION 1000000L/p>
p>int main(void)
{
int i;
struct timespec slptm;
long tdif;
struct timeval tend, tstart;/p>
p> slptm.tv_sec = 0;
slptm.tv_nsec = 1000; //1000 ns = 1 us/p>
p> //struct sched_param param;
//param.sched_priority = 0;
//sched_setscheduler(getpid(), SCHED_FIFO, param);/p>
p> 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