導航:首頁 > 操作系統 > linux定時器select

linux定時器select

發布時間:2022-06-01 03:30:56

1. 如何在linux下實現定時器

定時器Timer應用場景非常廣泛,在Linux下,有以下幾種方法:
1,使用sleep()和usleep()
其中sleep精度是1秒,usleep精度是1微妙,具體代碼就不寫了。使用這種方法缺點比較明顯,在Linux系統中,sleep類函數不能保證精度,尤其在系統負載比較大時,sleep一般都會有超時現象。
2,使用信號量SIGALRM + alarm()
這種方式的精度能達到1秒,其中利用了*nix系統的信號量機制,首先注冊信號量SIGALRM處理函數,調用alarm(),設置定時長度,代碼如下:

[cpp] view plain
#include <stdio.h>
#include <signal.h>

void timer(int sig)
{
if(SIGALRM == sig)
{
printf("timer\n");
alarm(1); //we contimue set the timer
}

return ;
}

int main()
{
signal(SIGALRM, timer); //relate the signal and function

alarm(1); //trigger the timer

getchar();

return 0;
}
alarm方式雖然很好,但是無法首先低於1秒的精度。

3,使用RTC機制
RTC機制利用系統硬體提供的Real Time Clock機制,通過讀取RTC硬體/dev/rtc,通過ioctl()設置RTC頻率,代碼如下:

[cpp] view plain
#include <stdio.h>
#include <linux/rtc.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
unsigned long i = 0;
unsigned long data = 0;
int retval = 0;
int fd = open ("/dev/rtc", O_RDONLY);

if(fd < 0)
{
perror("open");
exit(errno);
}

/*Set the freq as 4Hz*/
if(ioctl(fd, RTC_IRQP_SET, 1) < 0)
{
perror("ioctl(RTC_IRQP_SET)");
close(fd);
exit(errno);
}
/* Enable periodic interrupts */
if(ioctl(fd, RTC_PIE_ON, 0) < 0)
{
perror("ioctl(RTC_PIE_ON)");
close(fd);
exit(errno);
}

for(i = 0; i < 100; i++)
{
if(read(fd, &data, sizeof(unsigned long)) < 0)
{
perror("read");
close(fd);
exit(errno);

}
printf("timer\n");
}
/* Disable periodic interrupts */
ioctl(fd, RTC_PIE_OFF, 0);
close(fd);

return 0;
}
這種方式比較方便,利用了系統硬體提供的RTC,精度可調,而且非常高。
4,使用select()

這種方法在看APUE神書時候看到的,方法比較冷門,通過使用select(),來設置定時器;原理利用select()方法的第5個參數,第一個參數設置為0,三個文件描述符集都設置為NULL,第5個參數為時間結構體,代碼如下:

[cpp] view plain
#include <sys/time.h>
#include <sys/select.h>
#include <time.h>
#include <stdio.h>

/*seconds: the seconds; mseconds: the micro seconds*/
void setTimer(int seconds, int mseconds)
{
struct timeval temp;

temp.tv_sec = seconds;
temp.tv_usec = mseconds;

select(0, NULL, NULL, NULL, &temp);
printf("timer\n");

return ;
}

int main()
{
int i;

for(i = 0 ; i < 100; i++)
setTimer(1, 0);

return 0;
}
這種方法精度能夠達到微妙級別,網上有很多基於select()的多線程定時器,說明select()穩定性還是非常好。

總結:如果對系統要求比較低,可以考慮使用簡單的sleep(),畢竟一行代碼就能解決;如果系統對精度要求比較高,則可以考慮RTC機制和select()機制。

2. 嵌入式Linux下定時器問題,定時10us。

可以使用select函數實現定時,
timeval
tv;
tv.tv_usec=25;
tv.tv_sec=0;
select(1,NULL,NULL,NULL
&tv);

3. linux下的select函數是幹嘛的

select是用來設置超時時間的,其第一個參數本來是一個文件號,假如讀取該文件長時間沒有返回則超時跳出,而這部分代碼將文件號設置為0,說明只是為了控制延時
不過看你這部分代碼,明顯只是實現一個比較精確定時的sleep
這段代碼之所以這么做,是因為linux本身的sleep函數非常不準(windows也是一樣),在線程較多,cpu任務較重的時候,sleep函數的精確度根本無法達到要求
於是你這段代碼使用select來代替sleep更為精準,其精準程度和內核相關,如果內核的滴答頻率決定的,一般是100HZ也有1000hz的(因內核版本不同而不同),也就是說select做多可以精確到10ms,或者1ms,而sleep就做不到
於是
這段函數最重要的作用就是用高精確的select函數來代替低精確度的sleep函數,實現時間較為精準的延時

4. linux c下select函數的疑問

多個描述符返回准備好的那個,如果都為空,可以用作定時器

5. 怎樣在Linux下實現精確定時器

linux下使用select實現精確定時器
在編寫程序時,我們經常回用到定時器。本文講述如何使用select實現超級時鍾。使用select函數,我們能實現微妙級別精度的定時器。同時,select函數也是我們在編寫非阻塞程序時經常用到的一個函數。
首先看看select函數原型如下:
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);

參數說明:
slect的第一個參數nfds為fdset集合中最大描述符值加1,fdset是一個位數組,其大小限制為__FD_SETSIZE(1024),位數組的每一位代表其對應的描述符是否需要被檢查。
select的第二三四個參數表示需要關注讀、寫、錯誤事件的文件描述符位數組,這些參數既是輸入參數也是輸出參數,可能會被內核修改用於標示哪些描述符上發生了關注的事件。所以每次調用select前都需重新初始化fdset。
timeout參數為超時時間,該結構會被內核修改,其值為超時剩餘的時間。
利用select實現定時器,需要利用其timeout參數,注意到:
1)select函數使用了一個結構體timeval作為其參數。
2)select函數會更新timeval的值,timeval保持的值為剩餘時間。
如果我們指定了參數timeval的值,而將其他參數都置為0或者NULL,那麼在時間耗盡後,select函數便返回,基於這一點,我們可以利用select實現精確定時。
timeval的結構如下:
struct timeval{
long tv_sec;/*secons*
long tv_usec;/*microseconds*/
}

我們可以看出其精確到microseconds也即微妙。
一、秒級定時器

void seconds_sleep(unsigned seconds){
struct timeval tv;
tv.tv_sec=seconds;
tv.tv_usec=0;
int err;
do{
err=select(0,NULL,NULL,NULL,&tv);
}while(err<0 && errno==EINTR);
}

二、毫秒級別定時器

void milliseconds_sleep(unsigned long mSec){
struct timeval tv;
tv.tv_sec=mSec/1000;
tv.tv_usec=(mSec%1000)*1000;
int err;
do{
err=select(0,NULL,NULL,NULL,&tv);
}while(err<0 && errno==EINTR);
}

三、微妙級別定時器

void microseconds_sleep(unsigned long uSec){
struct timeval tv;
tv.tv_sec=uSec/1000000;
tv.tv_usec=uSec%1000000;
int err;
do{
err=select(0,NULL,NULL,NULL,&tv);
}while(err<0 && errno==EINTR);
}

現在我們來編寫幾行代碼看看定時效果吧。

#include <stdio.h>
#include <sys/time.h>
#include <errno.h>
int main()
{
int i;
for(i=0;i<5;++i){
printf("%d\n",i);
//seconds_sleep(1);
//milliseconds_sleep(1500);
microseconds_sleep(1900000);
}
}

註:timeval結構體中雖然指定了一個微妙級別的解析度,但內核支持的分別率往往沒有這么高,很多unix內核將超時值向上舍入成10ms的倍數。此外,加上內核調度延時現象,即定時器時間到後,內核還需要花一定時間調度相應進程的運行。因此,定時器的精度,最終還是由內核支持的分別率決定。

6. linux製作毫秒級定時器

1
nanosleep函數可以提供最高解析度,一般是納秒級
2
select、poll函數的定時是毫秒級,pselect是納秒級
以上三個函數都可以實現你的要求

7. select 循環定時器 linux

select函數
不是定時器,是I/O的復用,變成
非同步傳輸
。linux的定時器要用信號如alarm來完成秒級定時,用內核定時完成毫秒級定時器。

8. 關於在linux 下如何實現定時器的請教

我知道linux下的select函數可以用來實現高精度的sleep,定時器暫不清楚,找找posix的API吧!

9. 關於select定時器的問題

剛才試了一下 沒出現lz說的情況 雖說有誤差 但是沒那麼大
測試程序
#include <stdio.h>
#include <sys/socket.h>

useconds_t timepased(struct timeval t1, struct timeval t2)
{
if((t2.tv_sec - t1.tv_sec) == 0)
return (t2.tv_usec - t1.tv_usec);
t2.tv_usec += ((t2.tv_sec - t1.tv_sec) * 1000000);
return (t2.tv_usec - t1.tv_usec);
}

int main(int argc, char **argv)
{
struct timeval tv, be, af;
tv.tv_sec = 0;
tv.tv_usec = atoi(argv[1]);
gettimeofday(&be, NULL);
select(1, NULL, NULL, NULL, &tv);
gettimeofday(&af, NULL);
printf("%ld\n", timepased(be, af));
return 0;
}

運行情況
[wangy@r2p ~/study] $ ./select 100000
103964
[wangy@r2p ~/study] $ ./select 100000
103296
[wangy@r2p ~/study] $ ./select 100000
105189
[wangy@r2p ~/study] $ ./select 10000
15627
[wangy@r2p ~/study] $ ./select 10000
15343
[wangy@r2p ~/study] $ ./select 10000
19578
[wangy@r2p ~/study] $ ./select 10000
17587

lz也用這個程序測一下看看吧

10. 求linux毫秒級定時器的實現

1 nanosleep函數可以提供最高解析度,一般是納秒級
2 select、poll函數的定時是毫秒級,pselect是納秒級
以上三個函數都可以實現你的要求

閱讀全文

與linux定時器select相關的資料

熱點內容
不能修改的pdf 瀏覽:736
同城公眾源碼 瀏覽:474
一個伺服器2個埠怎麼映射 瀏覽:282
java字元串ascii碼 瀏覽:61
台灣雲伺服器怎麼租伺服器 瀏覽:461
旅遊手機網站源碼 瀏覽:316
android關聯表 瀏覽:929
安卓導航無聲音怎麼維修 瀏覽:322
app怎麼裝視頻 瀏覽:423
安卓系統下的軟體怎麼移到桌面 瀏覽:80
windows拷貝到linux 瀏覽:755
mdr軟體解壓和別人不一樣 瀏覽:888
單片機串列通信有什麼好處 瀏覽:324
游戲開發程序員書籍 瀏覽:848
pdf中圖片修改 瀏覽:275
匯編編譯後 瀏覽:480
php和java整合 瀏覽:835
js中執行php代碼 瀏覽:447
國產單片機廠商 瀏覽:62
蘋果手機怎麼設置不更新app軟體 瀏覽:289