小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

linux內(nèi)核中的信號機制

 lchjczw 2013-04-14

linux內(nèi)核中的信號機制--信號機制的管理結(jié)構(gòu)

Kernel version:2.6.14

CPU architecture:ARM920T

Author:ce123(http://blog.csdn.net/ce123)


信號只是一個數(shù)字,數(shù)字為0-31表示不同的信號,如下表所示。

編號

信號名

默認動作

說明

1

SIGHUP

進程終止

終端斷開連接

2

SIGINT

進程終止

用戶在鍵盤上按下CTRL+C

3

SIGQUIT

進程意外結(jié)束(Dump)

用戶在鍵盤上按下CTRL+\

4

SIGILL

進程意外結(jié)束(Dump)

遇到非法指令

5

SIGTRAP

進程意外結(jié)束(Dump)

遇到斷電,用于調(diào)試

6

SIGABRT/SIGIOT

進程意外結(jié)束(Dump)

 

7

SIGBUS

進程意外結(jié)束(Dump)

總線錯誤

8

SIGFPE

進程意外結(jié)束(Dump)

浮點異常

9

SIGKILL

進程終止

其他進程發(fā)送SIGKILL將導致目標進程終止

10

SIGUSR1

進程終止

應用程序可自定義使用

11

SIGSEGV

進程意外結(jié)束(Dump)

非法的內(nèi)存訪問

12

SIGUSR2

進程終止

應用程序可自定義使用

13

SIGPIPE

進程終止

管道讀取端已經(jīng)關(guān)閉,寫入端進程會收到該信號

14

SIGALRM

進程終止

定時器到時

15

SIGTERM

進程終止

發(fā)送該信號使目標進程終止

16

SIGSTKFLT

進程終止

堆線錯誤

17

SIGCHLD

忽略

子進程退出時會向父進程發(fā)送該信號

18

SIGCONT

忽略

進程繼續(xù)執(zhí)行

19

SIGSTOP

進程暫停

發(fā)送該信號會使目標進程進入TASK_STOPPED狀態(tài)

20

SIGTSTP

進程暫停

在終端上按下CTRL+Z

21

SIGTTIN

進程暫停

后臺進程從控制終端讀取數(shù)據(jù)

22

SIGTTOU

進程暫停

后臺進程從控制終端讀取數(shù)據(jù)

23

SIGURG

忽略

socket收到設(shè)置緊急指針標志的網(wǎng)絡(luò)數(shù)據(jù)包

24

SIGXCPU

進程意外結(jié)束(Dump)

進程使用CPU已經(jīng)超過限制

25

SIGXFSZ

進程意外結(jié)束(Dump)

進程使用CPU已經(jīng)超過限制

26

SIGVTALRM

進程終止

進程虛擬定時器到期

27

SIGPROF

進程終止

進程Profile定時器到期

28

SIGMNCH

忽略

進程終端窗口大小改變

29

SIGIO

進程暫停

用于異步IO

29

SIGPOLL

進程暫停

用于異步IO

30

SIGPWR

進程暫停

電源失效

31

SIGUNUSED

進程暫停

保留未使用

注意在上標中的默認動作是指,在沒有任何程序為相應的信號設(shè)置信號處理函數(shù)的情況下,內(nèi)核接收到該信號的默認處理方式,但在實際中,有可能不是這樣的。另外,在這里,進程終止一般是指進程通過do_exit()退出,進程意外結(jié)束(Dump)則表示進程遇到了一個異常。默認情況下,內(nèi)核會根據(jù)進程當時的內(nèi)存情況,在進程的當前目錄中生成一個Core Dump文件,以后用戶可以通過這個文件分析進程異常的原因。這個工作主要通過do_coredump()來完成。

由于早期只有31個信號,內(nèi)核僅僅使用一個32位的變量signal來表示進程接收到的信號,因此如果要向一個進程發(fā)送一個信號,就把signal的第n位設(shè)置為1,這非常類似中斷請求寄存器SRCPND寄存器,同時,還有一個blocked的變量,用來屏蔽信號,這類似中斷屏蔽寄存器INTMSK。這樣做的好處是可以“很快”判斷出一個進程收到了哪些信號,如果采用鏈表或者數(shù)組,則需要掃描整個隊列,但這也帶來了新的問題,如果向一個進程發(fā)送了SIGINT信號,在這個信號處理之前,再次發(fā)送SIGINT,當這個進程開始處理信號時,它只知道收到了SIGINT信號,而無法判斷出有幾個SIGINT需要處理。此后加入了信號隊列,把收到的信號保存在這個隊列中,就可以很好的解決這個問題了。但是為了兼容的目的,仍能保留了舊的信號處理方式,因此1-32還是按原有的方式進行處理,而33-64則使用新的機制,為了區(qū)別對待,編號為33-64的信號又稱為實時信號。需要注意的是:這里的“實時”和實時操作系統(tǒng)中的“實時”沒有任何聯(lián)系,實時信號在處理速度上并不會比普通信號快,它們之間的區(qū)別就是:普通信號會對多次的同一個信號進行“合并”處理,而實時信號會一一處理。因此我們這里僅討論普通信號。

信號機制的相關(guān)管理結(jié)構(gòu)位于task_struct結(jié)構(gòu)中,其主要結(jié)構(gòu)如下圖所示。


實時信號引入了信號隊列,為了處理上的方便,普通信號也使用了信號隊列,僅僅從數(shù)字上無法區(qū)分實時信號和普通信號。由于在linux中,進程對象和線程對象都是task_struct,因此需要區(qū)別對待線程的信號和進程的信號。在上圖中,Private Signal Queue是線程(在linux中稱為輕權(quán)進程)信號隊列,而Shared Signal Queue是進程(在linux中被稱為進程組)信號隊列。對于進程信號,則由進程組中的每一個線程共享。例如,在上圖中,pending和shared_pending分別是Private Signal Queue和Shared Signal Queue其類型都是sigpending(/include/linux/signal.h),定義如下:

  1. struct sigpending {  
  2.     struct list_head list;  
  3.     sigset_t signal;  
  4. };  

list用于連接信號隊列,signal是一個位圖,每一位表示一個對應的信號,用于指示信號隊列中有哪些信號等待處理,其類型為sigset_t(include/asm-arm/signal.h),其定義如下:

  1. #define _NSIG       64  
  2. #define _NSIG_BPW   32  
  3. #define _NSIG_WORDS (_NSIG / _NSIG_BPW)  
  4.   
  5.   
  6. typedef struct {  
  7.     unsigned long sig[_NSIG_WORDS];  
  8. } sigset_t;  

sigset_t是一個數(shù)組,總共有64位,對應64個信號位圖(32個普通信號和32個實時信號)。在以后的信號發(fā)送的分析中,我們會看到,對于普通信號,只需要把sigset_t中對應的位置1就可以了,而對于實時信號,還需要把相關(guān)信息添加到list的信號隊列,信號隊列類型為sigqueue(include/linux/signal.h),定義如下:

  1. /*  
  2.  * Real Time signals may be queued.  
  3.  */  
  4.   
  5. struct sigqueue {  
  6.     struct list_head list;  
  7.     spinlock_t *lock;  
  8.     int flags;  
  9.     siginfo_t info;  
  10.     struct user_struct *user;  
  11. };  
sigqueue中的list是隊列鏈表指針,info為這個信號的相關(guān)信息,其定義如下(include/asm-generic/siginfo.h):

  1. typedef struct siginfo {  
  2.     int si_signo;  
  3.     int si_errno;  
  4.     int si_code;  
  5.   
  6.     union {  
  7.         int _pad[SI_PAD_SIZE];  
  8.   
  9.         /* kill() */  
  10.         struct {  
  11.             pid_t _pid;     /* sender's pid */  
  12.             __ARCH_SI_UID_T _uid;   /* sender's uid */  
  13.         } _kill;  
  14.   
  15.         /* POSIX.1b timers */  
  16.         struct {  
  17.             timer_t _tid;       /* timer id */  
  18.             int _overrun;       /* overrun count */  
  19.             char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];  
  20.             sigval_t _sigval;   /* same as below */  
  21.             int _sys_private;       /* not to be passed to user */  
  22.         } _timer;  
  23.   
  24.         /* POSIX.1b signals */  
  25.         struct {  
  26.             pid_t _pid;     /* sender's pid */  
  27.             __ARCH_SI_UID_T _uid;   /* sender's uid */  
  28.             sigval_t _sigval;  
  29.         } _rt;  
  30.   
  31.         /* SIGCHLD */  
  32.         struct {  
  33.             pid_t _pid;     /* which child */  
  34.             __ARCH_SI_UID_T _uid;   /* sender's uid */  
  35.             int _status;        /* exit code */  
  36.             clock_t _utime;  
  37.             clock_t _stime;  
  38.         } _sigchld;  
  39.   
  40.         /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */  
  41.         struct {  
  42.             void __user *_addr; /* faulting insn/memory ref. */  
  43. #ifdef __ARCH_SI_TRAPNO  
  44.             int _trapno;    /* TRAP # which caused the signal */  
  45. #endif  
  46.         } _sigfault;  
  47.   
  48.         /* SIGPOLL */  
  49.         struct {  
  50.             __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */  
  51.             int _fd;  
  52.         } _sigpoll;  
  53.     } _sifields;  
  54. } siginfo_t;  
上圖中的sighand保存信號的處理函數(shù)指針,其作用類似于中斷向量表,類型為sighand_struct(include/linux/sched.h),定義為:

  1. struct sighand_struct {  
  2.     atomic_t        count;  
  3.     struct k_sigaction  action[_NSIG];  
  4.     spinlock_t      siglock;  
  5. };  
_NSIG定義在asm-arm/signal.h中,為64,數(shù)組action,對應64個信號處理函數(shù)的相關(guān)信息,烈性為k_sigaction,在arm平臺上,k_sigaction(include/asm-arm/signal.h)是死噶長提哦你的一個包裝,定義如下:

  1. struct k_sigaction {  
  2.     struct sigaction sa;  
  3. };  
sigantion(include/asm-arm/signal.h)的定義如下:

  1. struct sigaction {  
  2.     __sighandler_t sa_handler;  
  3.     unsigned long sa_flags;  
  4.     __sigrestore_t sa_restorer;  
  5.     sigset_t sa_mask;       /* mask last for extensibility */  
  6. };  

sa_handler就是信號處理函數(shù)指針。另外在task_struct結(jié)構(gòu)中還有一個blocked可以用來屏蔽信號。明白了上面的主要數(shù)據(jù)結(jié)構(gòu)的作用之后,很容易想到信號的處理主要有以下幾方面。

  • 設(shè)置信號回調(diào)函數(shù):內(nèi)核吧函數(shù)的相關(guān)信息保存到對應的sigantion結(jié)構(gòu)中。
  • 信號的發(fā)送:通過相關(guān)系統(tǒng)調(diào)用吧一個指定的信號發(fā)送到目標進程,如果該信號沒有被屏蔽,就把信號的相關(guān)信息添加到信號隊列中,如果有必要就喚醒目標進程。
  • 信號響應:進程被喚醒后,根據(jù)信號隊列中的信息,調(diào)用信號回調(diào)函數(shù)。
我們再來看一下信號回調(diào)函數(shù),sa_handler的類型是__sihandler_t(include/asm-generic/singal.h),其定義為:
  1. typedef void __signalfn_t(int);  
  2. typedef __signalfn_t __user *__sighandler_t;  

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多