當(dāng)前位置:首頁 > 芯聞號 > 充電吧
[導(dǎo)讀]信號是Linux編程中非常重要的部分,本文將詳細介紹信號機制的基本概念、Linux對信號機制的大致實現(xiàn)方法、如何使用信號,以及有關(guān)信號的幾個系統(tǒng)調(diào)用。?信號機制是進程之間相互傳遞消息的一種方法,信號全

信號是Linux編程中非常重要的部分,本文將詳細介紹信號機制的基本概念、Linux對信號機制的大致實現(xiàn)方法、如何使用信號,以及有關(guān)信號的幾個系統(tǒng)調(diào)用。?

信號機制是進程之間相互傳遞消息的一種方法,信號全稱為軟中斷信號,也有人稱作軟中斷。從它的命名可以看出,它的實質(zhì)和使用很象中斷。所以,信號可以說是進程控制的一部分。?

一、信號的基本概念?

本節(jié)先介紹信號的一些基本概念,然后給出一些基本的信號類型和信號對應(yīng)的事件。基本概念對于理解和使用信號,對于理解信號機制都特別重要。下面就來看看什么是信號。?

1、基本概念?

軟中斷信號(signal,又簡稱為信號)用來通知進程發(fā)生了異步事件。進程之間可以互相通過系統(tǒng)調(diào)用kill發(fā)送軟中斷信號。內(nèi)核也可以因為內(nèi)部事件而給進程發(fā)送信號,通知進程發(fā)生了某個事件。注意,信號只是用來通知某進程發(fā)生了什么事件,并不給該進程傳遞任何數(shù)據(jù)。?

收 到信號的進程對各種信號有不同的處理方法。處理方法可以分為三類:第一種是類似中斷的處理程序,對于需要處理的信號,進程可以指定處理函數(shù),由該函數(shù)來處 理。第二種方法是,忽略某個信號,對該信號不做任何處理,就象未發(fā)生過一樣。第三種方法是,對該信號的處理保留系統(tǒng)的默認(rèn)值,這種缺省操作,對大部分的信 號的缺省操作是使得進程終止。進程通過系統(tǒng)調(diào)用signal來指定進程對某個信號的處理行為。?

在進程表的表項中有一個軟中斷信號域,該域中每一位對應(yīng)一個信號,當(dāng)有信號發(fā)送給進程時,對應(yīng)位置位。由此可以看出,進程對不同的信號可以同時保留,但對于同一個信號,進程并不知道在處理之前來過多少個。?

2、信號的類型?

發(fā)出信號的原因很多,這里按發(fā)出信號的原因簡單分類,以了解各種信號:?

(1) 與進程終止相關(guān)的信號。當(dāng)進程退出,或者子進程終止時,發(fā)出這類信號。?
(2) 與進程例外事件相關(guān)的信號。如進程越界,或企圖寫一個只讀的內(nèi)存區(qū)域(如程序正文區(qū)),或執(zhí)行一個特權(quán)指令及其他各種硬件錯誤。?
(3) 與在系統(tǒng)調(diào)用期間遇到不可恢復(fù)條件相關(guān)的信號。如執(zhí)行系統(tǒng)調(diào)用exec時,原有資源已經(jīng)釋放,而目前系統(tǒng)資源又已經(jīng)耗盡。?
(4) 與執(zhí)行系統(tǒng)調(diào)用時遇到非預(yù)測錯誤條件相關(guān)的信號。如執(zhí)行一個并不存在的系統(tǒng)調(diào)用。?
(5) 在用戶態(tài)下的進程發(fā)出的信號。如進程調(diào)用系統(tǒng)調(diào)用kill向其他進程發(fā)送信號。?
(6) 與終端交互相關(guān)的信號。如用戶關(guān)閉一個終端,或按下break鍵等情況。?
(7) 跟蹤進程執(zhí)行的信號。?

Linux支持的信號列表如下。很多信號是與機器的體系結(jié)構(gòu)相關(guān)的,首先列出的是POSIX.1中列出的信號:?

信號 值 處理動作 發(fā)出信號的原因?
----------------------------------------------------------------------?
SIGHUP 1 A 終端掛起或者控制進程終止?
SIGINT 2 A 鍵盤中斷(如break鍵被按下)?
SIGQUIT 3 C 鍵盤的退出鍵被按下?
SIGILL 4 C 非法指令?
SIGABRT 6 C 由abort(3)發(fā)出的退出指令?
SIGFPE 8 C 浮點異常?
SIGKILL 9 AEF Kill信號?
SIGSEGV 11 C 無效的內(nèi)存引用?
SIGPIPE 13 A 管道破裂: 寫一個沒有讀端口的管道?
SIGALRM 14 A 由alarm(2)發(fā)出的信號?
SIGTERM 15 A 終止信號?
SIGUSR1 30,10,16 A 用戶自定義信號1?
SIGUSR2 31,12,17 A 用戶自定義信號2?
SIGCHLD 20,17,18 B 子進程結(jié)束信號?
SIGCONT 19,18,25 進程繼續(xù)(曾被停止的進程)?
SIGSTOP 17,19,23 DEF 終止進程?
SIGTSTP 18,20,24 D 控制終端(tty)上按下停止鍵?
SIGTTIN 21,21,26 D 后臺進程企圖從控制終端讀?
SIGTTOU 22,22,27 D 后臺進程企圖從控制終端寫?

下面的信號沒在POSIX.1中列出,而在SUSv2列出?

信號 值 處理動作 發(fā)出信號的原因?
--------------------------------------------------------------------?
SIGBUS 10,7,10 C 總線錯誤(錯誤的內(nèi)存訪問)?
SIGPOLL A Sys V定義的Pollable事件,與SIGIO同義?
SIGPROF 27,27,29 A Profiling定時器到?
SIGSYS 12,-,12 C 無效的系統(tǒng)調(diào)用 (SVID)?
SIGTRAP 5 C 跟蹤/斷點捕獲?
SIGURG 16,23,21 B Socket出現(xiàn)緊急條件(4.2 BSD)?
SIGVTALRM 26,26,28 A 實際時間報警時鐘信號(4.2 BSD)?
SIGXCPU 24,24,30 C 超出設(shè)定的CPU時間限制(4.2 BSD)?
SIGXFSZ 25,25,31 C 超出設(shè)定的文件大小限制(4.2 BSD)?

(對于SIGSYS,SIGXCPU,SIGXFSZ,以及某些機器體系結(jié)構(gòu)下的SIGBUS,Linux缺省的動作是A (terminate),SUSv2 是C (terminate and dump core))。?

下面是其它的一些信號?

信號 值 處理動作 發(fā)出信號的原因?
----------------------------------------------------------------------?
SIGIOT 6 C IO捕獲指令,與SIGABRT同義?
SIGEMT 7,-,7?
SIGSTKFLT -,16,- A 協(xié)處理器堆棧錯誤?
SIGIO 23,29,22 A 某I/O操作現(xiàn)在可以進行了(4.2 BSD)?
SIGCLD -,-,18 A 與SIGCHLD同義?
SIGPWR 29,30,19 A 電源故障(System V)?
SIGINFO 29,-,- A 與SIGPWR同義?
SIGLOST -,-,- A 文件鎖丟失?
SIGWINCH 28,28,20 B 窗口大小改變(4.3 BSD, Sun)?
SIGUNUSED -,31,- A 未使用的信號(will be SIGSYS)?

(在這里,- 表示信號沒有實現(xiàn);有三個值給出的含義為,第一個值通常在Alpha和Sparc上有效,中間的值對應(yīng)i386和ppc以及sh,最后一個值對應(yīng)mips。信號29在Alpha上為SIGINFO / SIGPWR ,在Sparc上為SIGLOST。)?

處理動作一項中的字母含義如下?
A 缺省的動作是終止進程?
B 缺省的動作是忽略此信號?
C 缺省的動作是終止進程并進行內(nèi)核映像轉(zhuǎn)儲(dump core)?
D 缺省的動作是停止進程?
E 信號不能被捕獲?
F 信號不能被忽略?

上 面介紹的信號是常見系統(tǒng)所支持的。以表格的形式介紹了各種信號的名稱、作用及其在默認(rèn)情況下的處理動作。各種默認(rèn)處理動作的含義是:終止程序是指進程退 出;忽略該信號是將該信號丟棄,不做處理;停止程序是指程序掛起,進入停止?fàn)顩r以后還能重新進行下去,一般是在調(diào)試的過程中(例如ptrace系統(tǒng)調(diào) 用);內(nèi)核映像轉(zhuǎn)儲是指將進程數(shù)據(jù)在內(nèi)存的映像和進程在內(nèi)核結(jié)構(gòu)中存儲的部分內(nèi)容以一定格式轉(zhuǎn)儲到文件系統(tǒng),并且進程退出執(zhí)行,這樣做的好處是為程序員提 供了方便,使得他們可以得到進程當(dāng)時執(zhí)行時的數(shù)據(jù)值,允許他們確定轉(zhuǎn)儲的原因,并且可以調(diào)試他們的程序。?

注意 信號SIGKILL和SIGSTOP既不能被捕捉,也不能被忽略。信號SIGIOT與SIGABRT是一個信號??梢钥闯?,同一個信號在不同的系統(tǒng)中值可能不一樣,所以建議最好使用為信號定義的名字,而不要直接使用信號的值。?

二、信 號 機 制?

上 一節(jié)中介紹了信號的基本概念,在這一節(jié)中,我們將介紹內(nèi)核如何實現(xiàn)信號機制。即內(nèi)核如何向一個進程發(fā)送信號、進程如何接收一個信號、進程怎樣控制自己對信 號的反應(yīng)、內(nèi)核在什么時機處理和怎樣處理進程收到的信號。還要介紹一下setjmp和longjmp在信號中起到的作用。?

1、內(nèi)核對信號的基本處理方法?

內(nèi) 核給一個進程發(fā)送軟中斷信號的方法,是在進程所在的進程表項的信號域設(shè)置對應(yīng)于該信號的位。這里要補充的是,如果信號發(fā)送給一個正在睡眠的進程,那么要看 該進程進入睡眠的優(yōu)先級,如果進程睡眠在可被中斷的優(yōu)先級上,則喚醒進程;否則僅設(shè)置進程表中信號域相應(yīng)的位,而不喚醒進程。這一點比較重要,因為進程檢 查是否收到信號的時機是:一個進程在即將從內(nèi)核態(tài)返回到用戶態(tài)時;或者,在一個進程要進入或離開一個適當(dāng)?shù)牡驼{(diào)度優(yōu)先級睡眠狀態(tài)時。?

內(nèi)核處理一個進程收到的信號的時機是在一個進程從內(nèi)核態(tài)返回用戶態(tài)時。所以,當(dāng)一個進程在內(nèi)核態(tài)下運行時,軟中斷信號并不立即起作用,要等到將返回用戶態(tài)時才處理。進程只有處理完信號才會返回用戶態(tài),進程在用戶態(tài)下不會有未處理完的信號。?

內(nèi) 核處理一個進程收到的軟中斷信號是在該進程的上下文中,因此,進程必須處于運行狀態(tài)。前面介紹概念的時候講過,處理信號有三種類型:進程接收到信號后退 出;進程忽略該信號;進程收到信號后執(zhí)行用戶設(shè)定用系統(tǒng)調(diào)用signal的函數(shù)。當(dāng)進程接收到一個它忽略的信號時,進程丟棄該信號,就象沒有收到該信號似 的繼續(xù)運行。如果進程收到一個要捕捉的信號,那么進程從內(nèi)核態(tài)返回用戶態(tài)時執(zhí)行用戶定義的函數(shù)。而且執(zhí)行用戶定義的函數(shù)的方法很巧妙,內(nèi)核是在用戶棧上創(chuàng) 建一個新的層,該層中將返回地址的值設(shè)置成用戶定義的處理函數(shù)的地址,這樣進程從內(nèi)核返回彈出棧頂時就返回到用戶定義的函數(shù)處,從函數(shù)返回再彈出棧頂時, 才返回原先進入內(nèi)核的地方。這樣做的原因是用戶定義的處理函數(shù)不能且不允許在內(nèi)核態(tài)下執(zhí)行(如果用戶定義的函數(shù)在內(nèi)核態(tài)下運行的話,用戶就可以獲得任何權(quán) 限)。?

在信號的處理方法中有幾點特別要引起注意。第一,在一些系統(tǒng)中,當(dāng)一個進程處理完中斷信號返回用戶態(tài)之前,內(nèi)核清除用戶區(qū)中設(shè) 定的對該信號的處理例程的地址,即下一次進程對該信號的處理方法又改為默認(rèn)值,除非在下一次信號到來之前再次使用signal系統(tǒng)調(diào)用。這可能會使得進程 在調(diào)用signal之前又得到該信號而導(dǎo)致退出。在BSD中,內(nèi)核不再清除該地址。但不清除該地址可能使得進程因為過多過快的得到某個信號而導(dǎo)致堆棧溢 出。為了避免出現(xiàn)上述情況。在BSD系統(tǒng)中,內(nèi)核模擬了對硬件中斷的處理方法,即在處理某個中斷時,阻止接收新的該類中斷。?

第二個要 引起注意的是,如果要捕捉的信號發(fā)生于進程正在一個系統(tǒng)調(diào)用中時,并且該進程睡眠在可中斷的優(yōu)先級上,這時該信號引起進程作一次longjmp,跳出睡眠 狀態(tài),返回用戶態(tài)并執(zhí)行信號處理例程。當(dāng)從信號處理例程返回時,進程就象從系統(tǒng)調(diào)用返回一樣,但返回了一個錯誤代碼,指出該次系統(tǒng)調(diào)用曾經(jīng)被中斷。這要注 意的是,BSD系統(tǒng)中內(nèi)核可以自動地重新開始系統(tǒng)調(diào)用。?

第三個要注意的地方:若進程睡眠在可中斷的優(yōu)先級上,則當(dāng)它收到一個要忽略的信號時,該進程被喚醒,但不做longjmp,一般是繼續(xù)睡眠。但用戶感覺不到進程曾經(jīng)被喚醒,而是象沒有發(fā)生過該信號一樣。?

第 四個要注意的地方:內(nèi)核對子進程終止(SIGCLD)信號的處理方法與其他信號有所區(qū)別。當(dāng)進程檢查出收到了一個子進程終止的信號時,缺省情況下,該進程 就象沒有收到該信號似的,如果父進程執(zhí)行了系統(tǒng)調(diào)用wait,進程將從系統(tǒng)調(diào)用wait中醒來并返回wait調(diào)用,執(zhí)行一系列wait調(diào)用的后續(xù)操作(找 出僵死的子進程,釋放子進程的進程表項),然后從wait中返回。SIGCLD信號的作用是喚醒一個睡眠在可被中斷優(yōu)先級上的進程。如果該進程捕捉了這個 信號,就象普通信號處理一樣轉(zhuǎn)到處理例程。如果進程忽略該信號,那么系統(tǒng)調(diào)用wait的動作就有所不同,因為SIGCLD的作用僅僅是喚醒一個睡眠在可被 中斷優(yōu)先級上的進程,那么執(zhí)行wait調(diào)用的父進程被喚醒繼續(xù)執(zhí)行wait調(diào)用的后續(xù)操作,然后等待其他的子進程。?

如果一個進程調(diào)用signal系統(tǒng)調(diào)用,并設(shè)置了SIGCLD的處理方法,并且該進程有子進程處于僵死狀態(tài),則內(nèi)核將向該進程發(fā)一個SIGCLD信號。?

2、setjmp和longjmp的作用?

前面在介紹信號處理機制時,多次提到了setjmp和longjmp,但沒有仔細說明它們的作用和實現(xiàn)方法。這里就此作一個簡單的介紹。?

在 介紹信號的時候,我們看到多個地方要求進程在檢查收到信號后,從原來的系統(tǒng)調(diào)用中直接返回,而不是等到該調(diào)用完成。這種進程突然改變其上下文的情況,就是 使用setjmp和longjmp的結(jié)果。setjmp將保存的上下文存入用戶區(qū),并繼續(xù)在舊的上下文中執(zhí)行。這就是說,進程執(zhí)行一個系統(tǒng)調(diào)用,當(dāng)因為資 源或其他原因要去睡眠時,內(nèi)核為進程作了一次setjmp,如果在睡眠中被信號喚醒,進程不能再進入睡眠時,內(nèi)核為進程調(diào)用longjmp,該操作是內(nèi)核 為進程將原先setjmp調(diào)用保存在進程用戶區(qū)的上下文恢復(fù)成現(xiàn)在的上下文,這樣就使得進程可以恢復(fù)等待資源前的狀態(tài),而且內(nèi)核為setjmp返回1,使 得進程知道該次系統(tǒng)調(diào)用失敗。這就是它們的作用。?

三、有關(guān)信號的系統(tǒng)調(diào)用?

前面兩節(jié)已經(jīng)介紹了有關(guān)信號的大部分知 識。這一節(jié)我們來了解一下這些系統(tǒng)調(diào)用。其中,系統(tǒng)調(diào)用signal是進程用來設(shè)定某個信號的處理方法,系統(tǒng)調(diào)用kill是用來發(fā)送信號給指定進程的。這 兩個調(diào)用可以形成信號的基本操作。后兩個調(diào)用pause和alarm是通過信號實現(xiàn)的進程暫停和定時器,調(diào)用alarm是通過信號通知進程定時器到時。所 以在這里,我們還要介紹這兩個調(diào)用。?

1、signal 系統(tǒng)調(diào)用?

系統(tǒng)調(diào)用signal用來設(shè)定某個信號的處理方法。該調(diào)用聲明的格式如下:?
void (*signal(int signum, void (*handler)(int)))(int);?
在使用該調(diào)用的進程中加入以下頭文件:?
#include?

上述聲明格式比較復(fù)雜,如果不清楚如何使用,也可以通過下面這種類型定義的格式來使用(POSIX的定義):?
typedef void (*sighandler_t)(int);?
sighandler_t signal(int signum, sighandler_t handler);?
但這種格式在不同的系統(tǒng)中有不同的類型定義,所以要使用這種格式,最好還是參考一下聯(lián)機手冊。?

在調(diào)用中,參數(shù)signum指出要設(shè)置處理方法的信號。第二個參數(shù)handler是一個處理函數(shù),或者是?
SIG_IGN:忽略參數(shù)signum所指的信號。?
SIG_DFL:恢復(fù)參數(shù)signum所指信號的處理方法為默認(rèn)值。?

傳遞給信號處理例程的整數(shù)參數(shù)是信號值,這樣可以使得一個信號處理例程處理多個信號。系統(tǒng)調(diào)用signal返回值是指定信號signum前一次的處理例程或者錯誤時返回錯誤代碼SIG_ERR。下面來看一個簡單的例子:?

#include?
#include?
#include?
void sigroutine(int dunno) { /* 信號處理例程,其中dunno將會得到信號的值 */?
switch (dunno) {?
case 1:?
printf("Get a signal -- SIGHUP ");?
break;?
case 2:?
printf("Get a signal -- SIGINT ");?
break;?
case 3:?
printf("Get a signal -- SIGQUIT ");?
break;?
}?
return;?
}?

int main() {?
printf("process id is %d ",getpid());?
signal(SIGHUP, sigroutine); //* 下面設(shè)置三個信號的處理方法?
signal(SIGINT, sigroutine);?
signal(SIGQUIT, sigroutine);?
for (;;) ;?
}?

其中信號SIGINT由按下Ctrl-C發(fā)出,信號SIGQUIT由按下Ctrl-發(fā)出。該程序執(zhí)行的結(jié)果如下:?

localhost:~$ ./sig_test?
process id is 463?
Get a signal -SIGINT //按下Ctrl-C得到的結(jié)果?
Get a signal -SIGQUIT //按下Ctrl-得到的結(jié)果?
//按下Ctrl-z將進程置于后臺?
[1]+ Stopped ./sig_test?
localhost:~$ bg?
[1]+ ./sig_test &?
localhost:~$ kill -HUP 463 //向進程發(fā)送SIGHUP信號?
localhost:~$ Get a signal – SIGHUP?
kill -9 463 //向進程發(fā)送SIGKILL信號,終止進程?
localhost:~$?

2、kill 系統(tǒng)調(diào)用?

系統(tǒng)調(diào)用kill用來向進程發(fā)送一個信號。該調(diào)用聲明的格式如下:?
int kill(pid_t pid, int sig);?
在使用該調(diào)用的進程中加入以下頭文件:?
#include?
#include?

該 系統(tǒng)調(diào)用可以用來向任何進程或進程組發(fā)送任何信號。如果參數(shù)pid是正數(shù),那么該調(diào)用將信號sig發(fā)送到進程號為pid的進程。如果pid等于0,那么信 號sig將發(fā)送給當(dāng)前進程所屬進程組里的所有進程。如果參數(shù)pid等于-1,信號sig將發(fā)送給除了進程1和自身以外的所有進程。如果參數(shù)pid小于- 1,信號sig將發(fā)送給屬于進程組-pid的所有進程。如果參數(shù)sig為0,將不發(fā)送信號。該調(diào)用執(zhí)行成功時,返回值為0;錯誤時,返回-1,并設(shè)置相應(yīng) 的錯誤代碼errno。下面是一些可能返回的錯誤代碼:?
EINVAL:指定的信號sig無效。?
ESRCH:參數(shù)pid指定的進程或進程組不存在。注意,在進程表項中存在的進程,可能是一個還沒有被wait收回,但已經(jīng)終止執(zhí)行的僵死進程。?
EPERM: 進程沒有權(quán)力將這個信號發(fā)送到指定接收信號的進程。因為,一個進程被允許將信號發(fā)送到進程pid時,必須擁有root權(quán)力,或者是發(fā)出調(diào)用的進程的UID 或EUID與指定接收的進程的UID或保存用戶ID(savedset-user-ID)相同。如果參數(shù)pid小于-1,即該信號發(fā)送給一個組,則該錯誤 表示組中有成員進程不能接收該信號。?

3、pause系統(tǒng)調(diào)用?

系統(tǒng)調(diào)用pause的作用是等待一個信號。該調(diào)用的聲明格式如下:?
int pause(void);?
在使用該調(diào)用的進程中加入以下頭文件:?
#include?

該調(diào)用使得發(fā)出調(diào)用的進程進入睡眠,直到接收到一個信號為止。該調(diào)用總是返回-1,并設(shè)置錯誤代碼為EINTR(接收到一個信號)。下面是一個簡單的范例:?

#include?
#include?
#include?
void sigroutine(int unused) {?
printf("Catch a signal SIGINT ");?
}?

int main() {?
signal(SIGINT, sigroutine);?
pause();?
printf("receive a signal ");?
}?

在這個例子中,程序開始執(zhí)行,就象進入了死循環(huán)一樣,這是因為進程正在等待信號,當(dāng)我們按下Ctrl-C時,信號被捕捉,并且使得pause退出等待狀態(tài)。?

4、alarm和 setitimer系統(tǒng)調(diào)用?

系統(tǒng)調(diào)用alarm的功能是設(shè)置一個定時器,當(dāng)定時器計時到達時,將發(fā)出一個信號給進程。該調(diào)用的聲明格式如下:?
unsigned int alarm(unsigned int seconds);?
在使用該調(diào)用的進程中加入以下頭文件:?
#include?

系 統(tǒng)調(diào)用alarm安排內(nèi)核為調(diào)用進程在指定的seconds秒后發(fā)出一個SIGALRM的信號。如果指定的參數(shù)seconds為0,則不再發(fā)送 SIGALRM信號。后一次設(shè)定將取消前一次的設(shè)定。該調(diào)用返回值為上次定時調(diào)用到發(fā)送之間剩余的時間,或者因為沒有前一次定時調(diào)用而返回0。?

注意,在使用時,alarm只設(shè)定為發(fā)送一次信號,如果要多次發(fā)送,就要多次使用alarm調(diào)用。?

對于alarm,這里不再舉例。現(xiàn)在的系統(tǒng)中很多程序不再使用alarm調(diào)用,而是使用setitimer調(diào)用來設(shè)置定時器,用getitimer來得到定時器的狀態(tài),這兩個調(diào)用的聲明格式如下:?
int getitimer(int which, struct itimerval *value);?
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);?
在使用這兩個調(diào)用的進程中加入以下頭文件:?
#include?

該系統(tǒng)調(diào)用給進程提供了三個定時器,它們各自有其獨有的計時域,當(dāng)其中任何一個到達,就發(fā)送一個相應(yīng)的信號給進程,并使得計時器重新開始。三個計時器由參數(shù)which指定,如下所示:?
TIMER_REAL:按實際時間計時,計時到達將給進程發(fā)送SIGALRM信號。?
ITIMER_VIRTUAL:僅當(dāng)進程執(zhí)行時才進行計時。計時到達將發(fā)送SIGVTALRM信號給進程。?
ITIMER_PROF:當(dāng)進程執(zhí)行時和系統(tǒng)為該進程執(zhí)行動作時都計時。與ITIMER_VIR-TUAL是一對,該定時器經(jīng)常用來統(tǒng)計進程在用戶態(tài)和內(nèi)核態(tài)花費的時間。計時到達將發(fā)送SIGPROF信號給進程。?

定時器中的參數(shù)value用來指明定時器的時間,其結(jié)構(gòu)如下:?
struct itimerval {?
struct timeval it_interval; /* 下一次的取值 */?
struct timeval it_value; /* 本次的設(shè)定值 */?
};?

該結(jié)構(gòu)中timeval結(jié)構(gòu)定義如下:?
struct timeval {?
long tv_sec; /* 秒 */?
long tv_usec; /* 微秒,1秒 = 1000000 微秒*/?
};?

在setitimer 調(diào)用中,參數(shù)ovalue如果不為空,則其中保留的是上次調(diào)用設(shè)定的值。定時器將it_value遞減到0時,產(chǎn)生一個信號,并將it_value的值設(shè) 定為it_interval的值,然后重新開始計時,如此往復(fù)。當(dāng)it_value設(shè)定為0時,計時器停止,或者當(dāng)它計時到期,而it_interval 為0時停止。調(diào)用成功時,返回0;錯誤時,返回-1,并設(shè)置相應(yīng)的錯誤代碼errno:?
EFAULT:參數(shù)value或ovalue是無效的指針。?
EINVAL:參數(shù)which不是ITIMER_REAL、ITIMER_VIRT或ITIMER_PROF中的一個。?

下面是關(guān)于setitimer調(diào)用的一個簡單示范,在該例子中,每隔一秒發(fā)出一個SIGALRM,每隔0.5秒發(fā)出一個SIGVTALRM信號:?

#include?
#include?
#include?
#include?
int sec;?

void sigroutine(int signo) {?
switch (signo) {?
case SIGALRM:?
printf("Catch a signal -- SIGALRM ");?
break;?
case SIGVTALRM:?
printf("Catch a signal -- SIGVTALRM ");?
break;?
}?
return;?
}?

int main() {?
struct itimerval value,ovalue,value2;?
sec = 5;?

printf("process id is %d ",getpid());?
signal(SIGALRM, sigroutine);?
signal(SIGVTALRM, sigroutine);?

value.it_value.tv_sec = 1;?
value.it_value.tv_usec = 0;?
value.it_interval.tv_sec = 1;?
value.it_interval.tv_usec = 0;?
setitimer(ITIMER_REAL, &value, &ovalue);?

value2.it_value.tv_sec = 0;?
value2.it_value.tv_usec = 500000;?
value2.it_interval.tv_sec = 0;?
value2.it_interval.tv_usec = 500000;?
setitimer(ITIMER_VIRTUAL, &value2, &ovalue);?

for (;;) ;?
}?

該例子的屏幕拷貝如下:?

localhost:~$ ./timer_test?
process id is 579?
Catch a signal – SIGVTALRM?
Catch a signal – SIGALRM?
Catch a signal – SIGVTALRM?
Catch a signal – SIGVTALRM?
Catch a signal – SIGALRM?
Catch a signal –GVTALRM

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉