linuxtimer
『壹』 linux kernel里timer怎麼用
定時器,有時也稱為動態定時器或內核定時器,是管理內核時間的基矗內核經常要推後執行某些代碼,比如下半部機制就是為了將工作推後執行。我們需要一種工具,使工作能夠在指定時間點上執行,正好在希望的時間點上,內核定時器正是這樣一種工具。 ...
『貳』 如何在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()機制。
『叄』 linux下的幾種時鍾和定時器機制
1. RTC(Real Time Clock)
所有PC都有RTC. 它和CPU和其他晶元獨立。它在電腦關機之後還可以正常運行。RTC可以在IRQ8上產生周期性中斷. 頻率在2Hz--8192HZ.
Linux只是把RTC用來獲取時間和日期. 當然它允許進程通過對/dev/rtc設備來對它進行編程。Kernel通過0x70和0x71 I/O埠來訪問RTC。
2. TSC(Time Stamp Counter)
80x86上的微處理器都有CLK輸入針腳. 從奔騰系列開始. 微處理器支持一個計數器. 每當一個時鍾信號來的時候. 計數器加1. 可以通過匯編指令rdtsc來得到計數器的值。通過calibrate_tsc可以獲得CPU的頻率. 它是通過計算大約5毫秒里tsc寄存器裡面的增加值來確認的。或者可以通過cat /proc/cpuinfo來獲取cpu頻率。tsc可以提供比PIT更精確的時間度量。
3. PIT(Programmable internval timer)
除了RTC和TSC. IBM兼容機提供了PIT。PIT類似微波爐的鬧鍾機制. 當時間到的時候. 提供鈴聲. PIT不是產生鈴聲. 而是產生一種特殊中斷. 叫定時器中斷或者時鍾中斷。它用來告訴內核一個間隔過去了。這個時間間隔也叫做一個滴答數。可以通過編譯內核是選擇內核頻率來確定。如內核頻率設為1000HZ,則時間間隔或滴答為1/1000=1微秒。滴答月短. 定時精度更高. 但是用戶模式的時間更短. 也就是說用戶模式下程序執行會越慢。滴答的長度以納秒形式存在tick_nsec變數裡面。PIT通過8254的0x40--0x43埠來訪問。它產生中斷號為IRQ 0.
下面是關於pIT裡面的一些宏定義:
HZ:每秒中斷數。
CLOCK_TICK_RATE:值是1,193,182. 它是8254晶元內部振盪器頻率。
LATCH:代表CLOCK_TICK_RATE和HZ的比率. 被用來編程PIT。
setup_pit_timer()如下:
spin_lock_irqsave(&i8253_lock, flags);
outb_p(0x34,0x43);
udelay(10);
outb_p(LATCH & 0xff, 0x40);
udelay(10);
outb (LATCH >> 8, 0x40);
spin_unlock_irqrestore(&i8253_lock, flags);
4. CPU Local Timer
最近的80x86架構的微處理器上的local apic提供了cpu local timer.他和pit區別在於它提供了one-shot和periodic中斷。它可以使中斷發送到特定cpu。one-shot中斷常用在實時系統裡面。
『肆』 Linux定時伺服器程序 timer (用c語言)
同學,你是段瀚聰老師的學生的吧?選了他的LINUX環境高級編程??
『伍』 Linux下的定時器,怎麼用
數為秒數,在經過指定秒數後,alarm會發出一個SIGALRM信號
singal函數用來綁定信號處理器函數,這里綁定的是timer,被綁定的函數必須固定為返回值void、參數int.
只需要alarm(時間)就設置了,可能由於getchar需要進入中斷導致信號被掛起所以沒反應,可以試試把getchar換成別的東西來延時看看。
關於更多Linux的學習,請查閱書籍《linux就該這么學》。
『陸』 linux/timer.h路徑在哪
輸入whereis time.h就知道了,whereis命令找某個頭文件的路徑非常適合,time.h頭文件是系統頭文件,應該找到的。它的路徑不同的Linux發行版應該是有些微差別的,用whereis命令查看一些才是最合適的。
『柒』 linux使用timer產生100us會很占資源嗎
系統資源肯定占,但是Timer本身耗費極少而已,而是應該關注Timer事件中的自定義方法。 你說的情況,沒必要用多個Timer啊,一個Timer中同時多個圖片各平移一幀不就可以了么?
『捌』 linux0.11版本中,關於函數do_timer的疑問
void do_timer (long cpl){
...
fn = next_timer->fn;
next_timer->fn = NULL;
next_timer = next_timer->next;
(fn)();
...
}
這個函數中的函數指針是在函數void add_timer(long jiffies, void (*fn)(void))中添加的。這個函數是供內核使用的,用戶空間的函數是不能調用add_timer的,也就是說 do_timer (long cpl)函數中的函數指針只會指向內核裡面的函數。
(我去看了linux0.11的源碼,用的地方確實只有
Floppy.c (kernel\blk_drv): add_timer(2,&transfer);
Floppy.c (kernel\blk_drv): add_timer(ticks_to_floppy_on(current_drive),&floppy_on_interrupt);
Sched.c (kernel):void add_timer(long jiffies, void (*fn)(void))
Sched.h (include\linux):extern void add_timer(long jiffies, void (*fn)(void));
)
所以的你的「內核不能直接訪問用戶空間函數問題」是不存在的。
我也是看到了http://bbs.chinaunix.net/thread-3727536-1-1.html這個帖子才想到的。
剛開始學這個,可能說的不對,多包涵。
『玖』 有誰會用linux裡面的定時器timer_list
這段代碼是Linux的一個內核模塊程序,timer_list也是Linux內核中的數據結構。模塊程序不是以main函數作為入口的。而是以mole_init指定。
mole_init/mole_exit分別用於指定模塊的載入和卸載函數。
載入模塊(insmod)時,會調用mytimer_init函數。這個函數設置一個定時器,在定時器超時時執行myfunc函數,指定函數參數為「Hello,world!」。
myfunc執行時,會輸出「Hello,world!」,mod_timer函數會將定時器重新計時,兩秒後到期。
因此整個代碼執行起來後的現象就是每兩秒輸出一次Hello,world!
『拾』 linux 加硬體定時器 timer 可否實時
一. Linux的硬體時間 PC機中的時間有三種硬體時鍾實現,這三種都是基於晶振產生的方波信號輸入。這三種時鍾為:(1)實時時鍾RTC ( Real Time Clock)