目錄
一. sleep()和usleep()
1.sleep()
2.usleep()
3.毫秒級延時(shí)
二. signal與alarm()
三.?select
四.?一些總結(jié)
一. sleep()和usleep()
????????優(yōu)點(diǎn)是簡單便捷,直接調(diào)用即可,但是缺點(diǎn)也很明顯,精度不夠,特別是在系統(tǒng)負(fù)載比較大時(shí),會(huì)發(fā)生超時(shí)現(xiàn)象。
1.sleep()
#include <unistd.h>
unsigned int sleep(unsigned int? ?seconds);
功能:執(zhí)行掛起指定的秒數(shù)
????????sleep()只能精確到秒級上。sleep()非系統(tǒng)調(diào)用,sleep()是在庫函數(shù)中實(shí)現(xiàn)的,它是通過alarm()來設(shè)定報(bào)警時(shí)間,使用sigsuspend()將進(jìn)程掛起在信號SIGALARM上。sleep()會(huì)令目前的進(jìn)程暫停,直到達(dá)到參數(shù)seconds 所指定的時(shí)間,或是被信號所中斷。
2.usleep()
#include <unistd.h>
void usleep(int? ? ?micro_seconds);
功能:把進(jìn)程掛起一段時(shí)間,單位是微秒(百萬分之一)
????????除了時(shí)間單位為微秒以外,在使用上與sleep()差不多。但實(shí)現(xiàn)是不同的,sleep是用alarm實(shí)現(xiàn)的,所以時(shí)間單位為s ,而usleep的時(shí)間單位為us,肯定不是由alarm實(shí)現(xiàn)的,所以說它們的實(shí)現(xiàn)不同,但都是linux用的,而window下不能用,因?yàn)槎际莝leep和usleep都是在unistd.h下定義的。
????????一般情況下,延遲時(shí)間數(shù)量級是秒的時(shí)候,盡可能使用sleep()函數(shù)。如果延遲時(shí)間為幾十毫秒(1ms = 1000us),或者更小,盡可能使用usleep()函數(shù)。這樣才能最佳的利用CPU時(shí)間。
3.毫秒級延時(shí)
? ? ? ? 因?yàn)閘inux下沒有現(xiàn)成的毫秒級延時(shí),這里我們可以自己簡單寫一個(gè):
#include <unistd.h>
void msleep(unsigned long ms)
{
struct timeval tv;
tv.tv_sec = ms/1000;
tv.tv_usec = (ms%1000)*1000;
select(0, NULL, NULL, NULL, &tv);
}
二. signal與alarm()
????????使用signal函數(shù)設(shè)定SIGALRM的處理函數(shù),然后使用alarm()定時(shí)發(fā)送SIGALRM來實(shí)現(xiàn)。??
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
int alarm_flag=1;
void timer(int sig)
{
if(SIGALRM == sig)
{
alarm_flag = 1;
}
return;
}
int main()
{
signal(SIGALRM, timer);
while( alrm_flag )
{
alarm_flag = 0;
printf("hello\n");
alarm(5);
}
return 0;
}
#include <unistd.h>
unsigned int alarm(unsigned int? ? ? ? ?seconds);? ? ? ??
功能:設(shè)置信號傳送鬧鐘
????????alarm()也稱為鬧鐘函數(shù),alarm()函數(shù)的主要功能是設(shè)置信號傳送鬧鐘,即?來設(shè)置信號SIGALRM 在經(jīng)過參數(shù)seconds 秒數(shù)后發(fā)送給?前的進(jìn)程。如果未設(shè)置信號SIGALARM 的處理函數(shù),那么alarm()默認(rèn)處理終?進(jìn)程。如果參數(shù)seconds為0,則之前設(shè)置的鬧鐘會(huì)被取消,并將剩下的時(shí)間返回。
????????PS:一個(gè)進(jìn)程只能有一個(gè)鬧鐘時(shí)間,如果在調(diào)用alarm之前已設(shè)置過鬧鐘時(shí)間,則任何以前的鬧鐘時(shí)間都被新值所代替。
三.?select
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval * timeout);
功能:用來等待文件描述詞狀態(tài)的改變。參數(shù)n代表最大的文件描述詞加1,參數(shù)readfds、writefds 和exceptfds稱為描述詞組,是用來回傳該描述詞的讀,寫或例外的狀況。
?????????這里就不詳細(xì)介紹select函數(shù)的參數(shù)及功能了,大家感興趣可以自行查閱。這里要實(shí)現(xiàn)定時(shí)器的話,把第一個(gè)參數(shù)設(shè)置為0,中間三個(gè)文件描述符集都設(shè)置為NULL,第五個(gè)參數(shù)為時(shí)間結(jié)構(gòu)體,我們主要就是使用參數(shù),把它設(shè)置為我們想要定時(shí)的頻率就好。
????????timeout為結(jié)構(gòu)timeval,用來設(shè)置select()的等待時(shí)間,其結(jié)構(gòu)定義如下:
struct timeval
{
????????time_t? ? ? ? tv_sec;
? ? ? ? time_t? ? ? ? tv_usec;
};
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
void timer_s(unsigned long s, unsigned long us)
{
struct timeval tv;
tv.tv_sec = s;
tv.tv_usec = us;
select(0, NULL, NULL, NULL, &tv);
}
int main()
{
while(1)
{
printf("hello\n");
timer_s(3, 0);
}
return 0;
}
四.?一些總結(jié)
????????大家根據(jù)自己需求選擇,這是在網(wǎng)上扒下來的一張圖,原文鏈接如下:文章來源:http://www.zghlxwxcb.cn/news/detail-590625.html
Linux中的sleep、usleep、nanosleep、poll和select不同的sleep方式https://mp.weixin.qq.com/s?src=11×tamp=1680196399&ver=4438&signature=LzDVJT7uLU7DuxA6qxK8Sm4FqjJw8G347mhB56nkDIb5R2XQsifqz-NFi1nmisdVYxrrRNgLVKIJqjN4koJ59oTtTBWunbaWVMV7u6dNydmBRf-DA9aR6yVNKkbJF*oI&new=1文章來源地址http://www.zghlxwxcb.cn/news/detail-590625.html
到了這里,關(guān)于linux下實(shí)現(xiàn)定時(shí)器的三種簡單方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!