理解SIGALRM信號

SIGALRM信號是操作系統中的其中一個信號。他的作用是設置進程隔多久後會收到一個SIGALRM信號。下面我們看一下他的實現原理。
    alarm系統調用是設置多久觸發SIGALRM信號的函數。下面是他的聲明。

#include <unistd.h>
unsigned alarm(unsigned seconds);

我們看看實現。

int sys_alarm(long seconds)
{
	int old = current->alarm;
	// 算出原來的時間
	if (old)
		old = (old - jiffies) / HZ;
	/*
		系統每隔n秒觸發一次時鐘中斷。jiffies是系統發生時鐘中斷的次數。
		1秒等於HZ個jiffies,這裏就是算出jiffies數,即時鐘中斷髮生多少次後觸發SIGALRM信號
	*/
	current->alarm = (seconds>0)?(jiffies+HZ*seconds):0;
	// 返回舊的
	return (old);
}

我們看到PCB中使用alarm字段記錄了SIGALRM信號觸發的時間。我們再來看一下觸發的時機。

 */
void schedule(void)
{
	int i,next,c;
	struct task_struct ** p;

	// 遍歷進程
	for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
		if (*p) {
			/*
				判斷是否設置了alarm並且過期了
				alarm < jiffies說明過期了。設置alarm信號,清除設置標記
			*/
			if ((*p)->alarm && (*p)->alarm < jiffies) {
					(*p)->signal |= (1<<(SIGALRM-1));
					(*p)->alarm = 0;
				}
		}
		...
}

在進程調度的時候,系統會處理SIGALRM信號的邏輯,判斷是否可以觸發SIGALRM信號了。是的話在PCB中打上標記。但是這時候如果該進程沒有被調度執行,那SIGALRM信號的函數會被延遲執行。即這裏只是記錄信息的時機,不一定是執行的時機。
    另外在父進程創建子進程的時候(fork),子進程不會進程父進程的alarm信息(重置爲0),但是如果一個進程設置了SIGALRM然後通過execve系列函數執行新的程序時,alarm信息會被繼承下來。最後我們看一下用法。

#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <signal.h> 
 
void handle_alarm() 
{ 
    exit(0); 
} 
int main(int argc, char *argv[]) 
{ 
    signal(SIGALRM, handle_alarm); 
    alarm(10); 
    while(1) {} 
} 

進程在10秒或10秒之後觸發SIGALRM信號,然後執行信號處理函數,最後退出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章