歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux信號機制概述

Linux信號機制概述

日期:2017/3/1 10:13:32   编辑:Linux編程

還是先看看Linux中用戶空間怎麼運用的,用戶空間編程實例如下:

#include<signal.h>

#include<stdio.h>

#include<unistd.h>

/*下面為兩個新的信號操作函數*/

void handler(int sig)

{

printf("Receive signal :%u\n",sig);

}

void sigroutine(int num)

{

switch(num)

{

case 1:

printf("SIGUP signal\n");

break;

case 2:

printf("SIGINT signal\n");

break;

case 3:

printf("SIGQUIT signal\n");

break;

default:

break;

}

return;

}

int main(void)

{

struct sigaction sa;

int count;

sa.sa_handler=handler;

sigemptyset(&sa.sa_mask);

sa.sa_flags=0;

printf("task id is:%d\n",getpid());

/*下面四條語句為相應的信號設置新的處理方法*/

sigaction(SIGTERM,&sa,NULL);

signal(SIGHUP,sigroutine);

signal(SIGINT,sigroutine);

signal(SIGQUIT,sigroutine);

while(1)

{

sigsuspend(&sa.sa_mask);/*阻塞,一直等待信號到達*/

printf("loop\n");

}

return 0;

}

可見,用戶空間調用了很多系統調用來實現信號的編程,為了弄清楚他的內在原理,決定將內核中的實現做一個大致的梳理。為了理清思路,我們由內核中實現信號操作涉及的關鍵數據結構關系畫出下圖,我們看到,內核中的數據結構實現較簡單,主要分兩部分,一部分用於信號操作(即handler),由進程的sighand字段開始;另一部分用於信號的掛起,由進程的signal和pending字段索引。

由關系圖,我們大致觀其實現原理如下:

1, 進程的所有信號(現為32個)由一個數組task->sighand->action[]保存,數組的下標即為信號的ID,比如SIGQUIT等,每個操作由一個數據結構sigaction實現,該字段的sa_handler即為實現的操作;

2, 進程對掛起的信號有兩種隊列,一種為所有進程共享的。該隊列的每一項為一個sigqueue結構,通過該結構info字段的si_signo等屬性可以定位到對應的信號ID。其中sigset_t結構為一個32位整型,用於定位到ID,即類似位圖的表示。

我們看幾個最基本的操作於內核中的實現。

Copyright © Linux教程網 All Rights Reserved