歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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