亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 服務器 > Linux服務器 > 正文

淺談linux幾種定時函數的使用

2024-09-05 23:02:46
字體:
來源:轉載
供稿:網友

在程序開發過程中,我們時不時要用到一些定時器,通常如果時間精度要求不高,可以使用sleep,uslepp函數讓進程睡眠一段時間來實現定時,

前者單位為秒(s),后者為微妙(us);但有時候我們又不想讓進程睡眠阻塞在哪兒,我們需要進程正常執行,當到達規定的時間時再去執行相應的操作,

linux下面我們一般使用alarm函數跟setitimer函數來實現定時功能;

下面對這兩個函數進行詳細分析:

(1)alarm函數

alarm也稱為鬧鐘函數,它可以在進程中設置一個定時器,當定時器指定的時間到時,它向進程發送SIGALRM信號;

alarm函數原型如下:

unsigned int alarm(unsigned int seconds);//seconds 為指定的秒數

所需頭文件
  #include<unistd.h>

函數原型
  unsigned int alarm(unsigned int seconds)

函數參數
  seconds:指定秒數

函數返回值
  成功:如果調用此alarm()前,進程已經設置了鬧鐘時間,則返回上一個鬧鐘時間的剩余時間,否則返回0。
  出錯:-1

下面是alarm()函數的簡單例子:

void sigalrm_fn(int sig)   {   printf("alarm!/n");   alarm(2);   return; }  int main(void)  {   signal(SIGALRM, sigalrm_fn); //后面的函數必須是帶int參數的  alarm(1);   while(1)    pause();  }

(2)setitimer()函數

在linux下如果對定時要求不太精確的話,使用alarm()和signal()就行了,但是如果想要實現精度較高的定時功能的話,就要使用setitimer函數。

setitimer()為Linux的API,并非C語言的Standard Library,setitimer()有兩個功能,一是指定一段時間后,才執行某個function,二是每間格一段時間就執行某個function;

Linux為每個任務安排了3個內部定時器:

ITIMER_REAL:實時定時器,不管進程在何種模式下運行(甚至在進程被掛起時),它總在計數。定時到達,向進程發送SIGALRM信號。

ITIMER_VIRTUAL:這個不是實時定時器,當進程在用戶模式(即程序執行時)計算進程執行的時間。定時到達后向該進程發送SIGVTALRM信號。

ITIMER_PROF:進程在用戶模式(即程序執行時)和核心模式(即進程調度用時)均計數。定時到達產生SIGPROF信號。ITIMER_PROF記錄的時間比ITIMER_VIRTUAL多了進程調度所花的時間。

定時器在初始化是,被賦予一個初始值,隨時間遞減,遞減至0后發出信號,同時恢復初始值。在任務中,我們可以一種或者全部三種定時器,但同一時刻同一類型的定時器只能使用一個。

setitimer函數原型如下:

#include <sys/time.h>    int setitimer(int which, const struct itimerval *new_value,           struct itimerval *old_value); Timer values are defined by the following structures:      struct itimerval {        struct timeval it_interval; /* next value */        struct timeval it_value;  /* current value */      };      struct timeval {        time_t   tv_sec;     /* seconds */        suseconds_t tv_usec;    /* microseconds */      };

it_interval用來指定每隔多長時間執行任務, it_value用來保存當前時間離執行任務還有多長時間。比如說, 你指定it_interval為2秒(微秒為0),開始的時候我們把it_value的時間也設定為2秒(微秒為0),當過了一秒, it_value就減少一個為1, 再過1秒,則it_value又減少1,變為0,這個時候發出信號(告訴用戶時間到了,可以執行任務了),并且系統自動把it_value的時間重置為 it_interval的值,即2秒,再重新計數

下面是setitimer簡單實例:

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <signal.h>#include <sys/time.h>void test_func(){  static count = 0;  printf("count is %d/n", count++);}void init_sigaction(){  struct sigaction act;       act.sa_handler = test_func; //設置處理信號的函數  act.sa_flags = 0;  sigemptyset(&act.sa_mask);  sigaction(SIGPROF, &act, NULL);//時間到發送SIGROF信號}void init_time(){  struct itimerval val;       val.it_value.tv_sec = 1; //1秒后啟用定時器  val.it_value.tv_usec = 0;  val.it_interval = val.it_value; //定時器間隔為1s  setitimer(ITIMER_PROF, &val, NULL);}int main(int argc, char **argv){  init_sigaction();  init_time();  while(1);  return 0;}

可以看出每個一秒輸出一個count的值:

下面是運行結果:

[root@localhost 5th]# ./test
count is 0
count is 1
count is 2
count is 3
count is 4
count is 5
count is 6
count is 7
count is 8
count is 9

附錄:

signal

1. 頭文件
#include <signal.h>

2. 功能
設置某一信號的對應動作

3. 函數原型
void (*signal(int signum,void(* handler)(int)))(int);

分解來看:

typedef void (*sig_t) (int);
sig_t signal(int sig, sig_t func);

第一個參數是目標信號。func參數是一個指針,指向某個處理該信號的函數。這個處理信號函數帶有一個int型參數,并應返回void。
func參數也可以設定為下面的一些值:
SIG_IGN: 如果func參數被設置為SIG_IGN,該信號將被忽略。
SIG_DFL: 如果func參數被設置為SIG_DFL,該信號會按照確定行為處理。

4. sig信號的可能類型

1) #define SIGHUP 1 /* hangup */

SIGHUP是Unix系統管理員很常用的一個信號。許多后臺服務進程在接受到該信號后將會重新讀取它們的配置文件。然而,該信號的實際功能是通知進程它的控制終端被斷開。缺省行為是終止進程。

2) #define SIGINT 2 /* interrupt */

對于Unix使用者來說,SIGINT是另外一個常用的信號。許多shell的CTRL-C組合使得這個信號被大家所熟知。該信號的正式名字是中斷信號。缺省行為是終止進程。

3) #define SIGQUIT 3 /* quit */

SIGQUIT信號被用于接收shell的CTRL-/組合。另外,它還用于告知進程退出。這是一個常用信號,用來通知應用程序從容的(譯注:即在結束前執行一些退出動作)關閉。缺省行為是終止進程,并且創建一個核心轉儲。

4) #define SIGILL 4 /* illegal instr. (not reset when caught) */

如果正在執行的進程中包含非法指令,操作系統將向該進程發送SIGILL信號。如果你的程序使用了線程,或者pointer functions,那么可能的話可以嘗試捕獲該信號來協助調試。([color=Red]注意:原文這句為:“If your program makes use of use of threads, or pointer functions, try to catch this signal if possible for aid in debugging.”。中間的兩個use of use of,不知是原書排版的瑕疵還是我確實沒有明白其意義;另外,偶經常聽說functions pointer,對于pointer functions,google了一下,應該是fortran里面的東西,不管怎樣,還真不知道,確切含義還請知道的兄弟斧正。[/color])缺省行為是終止進程,并且創建一個核心轉儲。

5) #define SIGTRAP 5 /* trace trap (not reset when caught) */

SIGTRAP這個信號是由POSIX標準定義的,用于調試目的。當被調試進程接收到該信號時,就意味著它到達了某一個調試斷點。一旦這個信號被交付,被調試的進程就會停止,并且它的父進程將接到通知。缺省行為是終止進程,并且創建一個核心轉儲。

6) #define SIGABRT 6 /* abort() */

SIGABRT提供了一種在異常終止(abort)一個進程的同時創建一個核心轉儲的方法。然而如果該信號被捕獲,并且信號處理句柄沒有返回,那么進程不會終止。缺省行為是終止進程,并且創建一個核心轉儲。

7) #define SIGFPE 8 /* floating point exception */

當進程發生一個浮點錯誤時,SIGFPE信號被發送給該進程。對于那些處理復雜數學運算的程序,一般會建議你捕獲該信號。缺省行為是終止進程,并且創建一個核心轉儲。

8) #define SIGKILL 9 /* kill (cannot be caught or ignored) */

SIGKILL是這些信號中最難對付的一個。正如你在它旁邊的注釋中看到的那樣,這個信號不能被捕獲或忽略。一旦該信號被交付給一個進程,那么這個進程就會終止。然而,會有一些極少數情況SIGKILL不會終止進程。這些罕見的情形在處理一個“非中斷操作”(比如磁盤I/O)的時候發生。雖然這樣的情形極少發生,然而一旦發生的話,會造成進程死鎖。唯一結束進程的辦法就只有重新啟動了。缺省行為是終止進程。

9) #define SIGBUS 10 /* bus error */

如同它的名字暗示的那樣,CPU檢測到數據總線上的錯誤時將產生SIGBUS信號。當程序嘗試去訪問一個沒有正確對齊的內存地址時就會產生該信號。缺省行為是終止進程,并且創建一個核心轉儲。

10) #define SIGSEGV 11 /* segmentation violation */

SIGSEGV是另一個C/C++程序員很熟悉的信號。當程序沒有權利訪問一個受保護的內存地址時,或者訪問無效的虛擬內存地址(臟指針,dirty pointers,譯注:由于沒有和后備存儲器中內容進行同步而造成。關于野指針,可以參見http://en.wikipedia.org/wiki/Wild_pointer 的解釋。)時,會產生這個信號。缺省行為是終止進程,并且創建一個核心轉儲。

11) #define SIGSYS 12 /* non-existent system call invoked */

SIGSYS信號會在進程執行一個不存在的系統調用時被交付。操作系統會交付該信號,并且進程會被終止。缺省行為是終止進程,并且創建一個核心轉儲。

12) #define SIGPIPE 13 /* write on a pipe with no one to read it */

管道的作用就像電話一樣,允許進程之間的通信。如果進程嘗試對管道執行寫操作,然而管道的另一邊卻沒有回應者時,操作系統會將SIGPIPE信號交付給這個討厭的進程(這里就是那個打算寫入的進程)。缺省行為是終止進程。

13) #define SIGALRM 14 /* alarm clock */

在進程的計時器到期的時候,SIGALRM信號會被交付(delivered)給進程。這些計時器由本章后面將會提及
的setitimer和alarm調用設置。缺省行為是終止進程。

14) #define SIGTERM 15 /* software termination signal from kill */

SIGTERM信號被發送給進程,通知該進程是時候終止了,并且在終止之前做一些清理活動。SIGTERM信號是Unix的kill命令發送的缺省信號,同時也是操作系統關閉時向進程發送的缺省信號。缺省行為是終止進程。

15) #define SIGURG 16 /* urgent condition on IO channel */

在進程已打開的套接字上發生某些情況時,SIGURG將被發送給該進程。如果進程不捕獲這個信號的話,那么將被丟棄。缺省行為是丟棄這個信號。

16) #define SIGSTOP 17 /* sendable stop signal not from tty */

本信號不能被捕獲或忽略。一旦進程接收到SIGSTOP信號,它會立即停止(stop),直到接收到另一個SIGCONT
信號為止。缺省行為是停止進程,直到接收到一個SIGCONT信號為止。

17) #define SIGTSTP 18 /* stop signal from tty */

SIGSTP與SIGSTOP類似,它們的區別在于SIGSTP信號可以被捕獲或忽略。當shell從鍵盤接收到CTRL-Z的時候就會交付(deliver)這個信號給進程。缺省行為是停止進程,直到接收到一個SIGCONT信號為止。

18) #define SIGCONT 19 /* continue a stopped process */

SIGCONT也是一個有意思的信號。如前所述,當進程停止的時候,這個信號用來告訴進程恢復運行。該信號的有趣的地方在于:它不能被忽略或阻塞,但可以被捕獲。這樣做很有意義:因為進程大概不愿意忽略或阻塞SIGCONT信號,否則,如果進程接收到SIGSTOP或SIGSTP的時候該怎么辦?缺省行為是丟棄該信號。

19) #define SIGCHLD 20 /* to parent on child stop or exit */

SIGCHLD是由Berkeley Unix引入的,并且比SRV 4 Unix上的實現有更好的接口。(如果信號是一個沒有追溯能力的過程(not a retroactive process),那么BSD的SIGCHID信號實現會比較好。在system V Unix的實現中,如果進程要求捕獲該信號,操作系統會檢查是否存在有任何未完成的子進程(這些子進程是已經退出exit)的子進程,并且在等待調用wait的父進程收集它們的狀態)。如果子進程退出的時候附帶有一些終止信息(terminating information),那么信號處理句柄就會被調用。所以,僅僅要求捕獲這個信號會導致信號處理句柄被調用(譯注:即是上面說的“信號的追溯能力”),而這是卻一種相當混亂的狀況。)一旦一個進程的子進程狀態發生改變,SIGCHLD信號就會被發送給該進程。就像我在前面章節提到的,父進程雖然可以fork出子進程,但沒有必要等待子進程退出。一般來說這是不太好的,因為這樣的話,一旦進程退出就可能會變成一個僵尸進程。可是如果父進程捕獲SIGCHLD信號的話,它就可以使用wait系列調用中的某一個去收集子進程狀態,或者判斷發生了什么事情。當發送SIGSTOP,SIGSTP或SIGCONF信號給子進程時,SIGCHLD信號也會被發送給父進程。缺省行為是丟棄該信號。

20) #define SIGTTIN 21 /* to readers pgrp upon background tty read */

當一個后臺進程嘗試進行一個讀操作時,SIGTTIN信號被發送給該進程。進程將會阻塞直到接收到SIGCONT信號為止。缺省行為是停止進程,直到接收到SIGCONT信號。

21) #define SIGTTOU 22 /* like TTIN if (tp->t_local<OSTOP) */

SIGTTOU信號與SIGTTIN很相似,不同之處在于SIGTTOU信號是由于后臺進程嘗試對一個設置了TOSTOP屬性的tty執行寫操作時才會產生。然而,如果tty沒有設置這個屬性,SIGTTOU就不會被發送。缺省行為是停止進程,直到接收到SIGCONT信號。

22) #define SIGIO 23 /* input/output possible signal */

如果進程在一個文件描述符上有I/O操作的話,SIGIO信號將被發送給這個進程。進程可以通過fcntl調用來設置。缺省行為是丟棄該信號。

23) #define SIGXCPU 24 /* exceeded CPU time limit */

如果一旦進程超出了它可以使用的CPU限制(CPU limit),SIGXCPU信號就被發送給它。這個限制可以使用隨后討論的setrlimit設置。缺省行為是終止進程。

24) #define SIGXFSZ 25 /* exceeded file size limit */

如果一旦進程超出了它可以使用的文件大小限制,SIGXFSZ信號就被發送給它。稍后我們會繼續討論這個信號。缺省行為是終止進程。

25) #define SIGVTALRM 26 /* virtual time alarm */

如果一旦進程超過了它設定的虛擬計時器計數時,SIGVTALRM信號就被發送給它。缺省行為是終止進程。

26) #define SIGPROF 27 /* profiling time alarm */

當設置了計時器時,SIGPROF是另一個將會發送給進程的信號。缺省行為是終止進程。

27) #define SIGWINCH 28 /* window size changes */

當進程調整了終端的行或列時(比如增大你的xterm的尺寸),SIGWINCH信號被發送給該進程。缺省行為是丟棄該信號。

28) #define SIGUSR1 29 /* user defined signal 1 */

29) #define SIGUSR2 30 /* user defined signal 2 */

SIGUSR1和SIGUSR2這兩個信號被設計為用戶指定。它們可以被設定來完成你的任何需要。換句話說,操作系統沒有任何行為與這兩個信號關聯。缺省行為是終止進程。(譯注:按原文的意思翻譯出來似乎這兩句話有點矛盾。)

5. 例子

5.1. Linux下的Ctrl+C在Windows下的實現

Linux下通常的做法:

signal(SIGINT, sigfunc); // 設置信號void sigfunc(int signo)  {   ... //處理信號相關的操作  }

以下是Linux下的Ctrl+C在Windows下的實現

#include <stdio.h>  #include <windows.h>  static is_loop = 1;  // 捕獲控制臺 Ctrl+C 事件的函數  BOOL CtrlHandler( DWORD fdwCtrlType )  {   switch (fdwCtrlType)   {   /* Handle the CTRL-C signal. */   case CTRL_C_EVENT:     printf("CTRL_C_EVENT /n");     break;   case CTRL_CLOSE_EVENT:     printf("CTRL_CLOSE_EVENT /n");     break;   case CTRL_BREAK_EVENT:     printf("CTRL_BREAK_EVENT /n");     break;   case CTRL_LOGOFF_EVENT:     printf("CTRL_LOGOFF_EVENT /n");     break;   case CTRL_SHUTDOWN_EVENT:     printf("CTRL_SHUTDOWN_EVENT /n");     break;   default:     return FALSE;   }   is_loop = 0;   return (TRUE);  }  int main(int argc, char *argv[])  {   printf("Set Console Ctrl Handler/n");   SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);   while (is_loop);   return 0;  }

5.2.Linux下的Ctrl+C在Windows下的實現二

#include <stdio.h>  #include <windows.h>  #define CONTRL_C_HANDLE() signal(3, exit)  int main(int argc, char *argv[])  {   printf("Set Console Ctrl Handler/n");   CONTRL_C_HANDLE();   while (1);   system("PAUSE");   return 0;  }

以上就是小編為大家帶來的淺談linux幾種定時函數的使用全部內容了,希望大家多多支持VEVB武林網~

 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲欧美另类人妖| 色偷偷888欧美精品久久久| 92福利视频午夜1000合集在线观看| 久久人人97超碰精品888| 欧美性20hd另类| 欧美成人精品xxx| 久久天天躁夜夜躁狠狠躁2022| 日韩精品欧美激情| 欧美精品久久久久久久| 懂色av影视一区二区三区| 亚洲精品国产精品乱码不99按摩| 91免费视频国产| 欧美日韩精品在线视频| 亚洲国产另类 国产精品国产免费| 亚洲人成网7777777国产| 精品久久久久久电影| 亚洲一区二区三区视频| 亚洲综合最新在线| 成人亚洲欧美一区二区三区| 日本伊人精品一区二区三区介绍| 久久久久久久爱| 色悠悠国产精品| 日韩成人在线电影网| 欧美国产一区二区三区| 日韩电影网在线| 中文字幕欧美日韩va免费视频| 国产在线精品自拍| 日韩在线精品视频| 亚洲电影免费观看高清完整版在线观看| 日韩精品在线视频美女| 欧美激情三级免费| 亚洲欧美国产va在线影院| 国色天香2019中文字幕在线观看| 成人伊人精品色xxxx视频| 日韩高清电影好看的电视剧电影| 国产精品免费小视频| 日韩国产高清污视频在线观看| 国产成+人+综合+亚洲欧洲| 日本成人在线视频网址| 欧美成人一区在线| 欧美成人午夜剧场免费观看| 黑人巨大精品欧美一区二区三区| 96精品久久久久中文字幕| 日韩av电影在线网| 国产精品wwwwww| 中文字幕精品www乱入免费视频| 久久中文字幕国产| 欧美高清视频免费观看| 成人性教育视频在线观看| 国产成人免费av电影| 伊是香蕉大人久久| 亚洲国产精彩中文乱码av| 亚洲欧美日本另类| 亚洲精品久久久久| 亚洲精品中文字幕女同| 欧美午夜无遮挡| 中文字幕精品一区久久久久| 97超级碰碰碰久久久| 欧美性猛交xxxx富婆| 久久好看免费视频| 国产免费一区二区三区在线能观看| 琪琪亚洲精品午夜在线| 日韩免费视频在线观看| 亚洲欧美国产精品va在线观看| 国产中文字幕亚洲| 久久久噜噜噜久久中文字免| 亚洲成人av片在线观看| 色爱精品视频一区| 国产精品一区二区三区毛片淫片| 亚洲国产精品久久久| 国产区亚洲区欧美区| 97在线视频精品| 国产精品久久一区| 日韩欧美亚洲一二三区| 亚洲欧美日韩精品久久亚洲区| 成人免费视频网址| 不卡av在线播放| 欧美成人精品h版在线观看| 91免费在线视频| 国产精品久久国产精品99gif| 5278欧美一区二区三区| 清纯唯美亚洲综合| 视频一区视频二区国产精品| 91亚洲精品久久久久久久久久久久| 日韩成人中文电影| 欧美激情视频免费观看| 日韩欧美在线免费观看| 日韩中文字幕视频| 午夜精品一区二区三区av| 亚洲另类xxxx| 免费91麻豆精品国产自产在线观看| 欧美日韩国产在线看| 亚洲精品国偷自产在线99热| 亚洲欧美日本伦理| 亚洲精品一区二区三区不| 国产精品视频免费观看www| 欧美黑人性生活视频| 热草久综合在线| 成人性生交大片免费看视频直播| 久久久久久久久91| 91精品久久久久久综合乱菊| 亚洲精品影视在线观看| 韩日欧美一区二区| 亚洲精品日韩激情在线电影| 97欧美精品一区二区三区| 久久免费精品日本久久中文字幕| 精品视频—区二区三区免费| 欧美一级淫片videoshd| 久久久伊人欧美| 97国产精品免费视频| 亚洲国产日韩精品在线| 91久久在线播放| 日韩精品欧美激情| 亚洲色图美腿丝袜| 欧美日本在线视频中文字字幕| 亚洲热线99精品视频| 一区二区三区在线播放欧美| 中文字幕亚洲激情| 国产情人节一区| 亚洲午夜精品久久久久久性色| 中文字幕无线精品亚洲乱码一区| 亚洲精品www久久久| 福利一区视频在线观看| 成人有码视频在线播放| 成人久久18免费网站图片| 欧美www视频在线观看| 狠狠久久五月精品中文字幕| 久久久噜噜噜久久| 国产精品视频在线观看| 亚洲电影免费观看高清完整版| 久久久久久免费精品| 亚洲高清一区二| 亚洲精品一区二三区不卡| 欧美一区二区色| 国产日韩欧美自拍| 亚洲第一区第一页| 国语自产精品视频在线看一大j8| 九九热r在线视频精品| 91久久精品国产| 欧美在线观看网站| 国产精品视频最多的网站| 在线成人中文字幕| 国产亚洲日本欧美韩国| 精品在线小视频| 日韩av资源在线播放| 亚洲国产精品资源| 精品福利一区二区| 中文字幕久久久| 亚洲国产日韩欧美在线99| 国产大片精品免费永久看nba| 91av网站在线播放| 欧美性xxxxxxx| 国产在线观看精品| 中文国产亚洲喷潮| 久久免费少妇高潮久久精品99| 久久免费福利视频| 国产综合久久久久| 国产一区二区三区视频在线观看| 欧美精品手机在线| 中文日韩电影网站| 亚洲精品久久久久久久久| 在线日韩日本国产亚洲| 97在线看免费观看视频在线观看| 岛国av午夜精品|