乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

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

       lchjczw 2013-04-14

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

      Kernel version:2.6.14

      CPU architecture:ARM920T

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


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

      編號

      信號名

      默認(rèn)動作

      說明

      1

      SIGHUP

      進(jìn)程終止

      終端斷開連接

      2

      SIGINT

      進(jìn)程終止

      用戶在鍵盤上按下CTRL+C

      3

      SIGQUIT

      進(jìn)程意外結(jié)束(Dump)

      用戶在鍵盤上按下CTRL+\

      4

      SIGILL

      進(jìn)程意外結(jié)束(Dump)

      遇到非法指令

      5

      SIGTRAP

      進(jìn)程意外結(jié)束(Dump)

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

      6

      SIGABRT/SIGIOT

      進(jìn)程意外結(jié)束(Dump)

       

      7

      SIGBUS

      進(jìn)程意外結(jié)束(Dump)

      總線錯誤

      8

      SIGFPE

      進(jìn)程意外結(jié)束(Dump)

      浮點(diǎn)異常

      9

      SIGKILL

      進(jìn)程終止

      其他進(jìn)程發(fā)送SIGKILL將導(dǎo)致目標(biāo)進(jìn)程終止

      10

      SIGUSR1

      進(jìn)程終止

      應(yīng)用程序可自定義使用

      11

      SIGSEGV

      進(jìn)程意外結(jié)束(Dump)

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

      12

      SIGUSR2

      進(jìn)程終止

      應(yīng)用程序可自定義使用

      13

      SIGPIPE

      進(jìn)程終止

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

      14

      SIGALRM

      進(jìn)程終止

      定時器到時

      15

      SIGTERM

      進(jìn)程終止

      發(fā)送該信號使目標(biāo)進(jìn)程終止

      16

      SIGSTKFLT

      進(jìn)程終止

      堆線錯誤

      17

      SIGCHLD

      忽略

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

      18

      SIGCONT

      忽略

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

      19

      SIGSTOP

      進(jìn)程暫停

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

      20

      SIGTSTP

      進(jìn)程暫停

      在終端上按下CTRL+Z

      21

      SIGTTIN

      進(jìn)程暫停

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

      22

      SIGTTOU

      進(jìn)程暫停

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

      23

      SIGURG

      忽略

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

      24

      SIGXCPU

      進(jìn)程意外結(jié)束(Dump)

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

      25

      SIGXFSZ

      進(jìn)程意外結(jié)束(Dump)

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

      26

      SIGVTALRM

      進(jìn)程終止

      進(jìn)程虛擬定時器到期

      27

      SIGPROF

      進(jìn)程終止

      進(jìn)程Profile定時器到期

      28

      SIGMNCH

      忽略

      進(jìn)程終端窗口大小改變

      29

      SIGIO

      進(jìn)程暫停

      用于異步IO

      29

      SIGPOLL

      進(jìn)程暫停

      用于異步IO

      30

      SIGPWR

      進(jìn)程暫停

      電源失效

      31

      SIGUNUSED

      進(jìn)程暫停

      保留未使用

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

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

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


      實(shí)時信號引入了信號隊列,為了處理上的方便,普通信號也使用了信號隊列,僅僅從數(shù)字上無法區(qū)分實(shí)時信號和普通信號。由于在linux中,進(jìn)程對象和線程對象都是task_struct,因此需要區(qū)別對待線程的信號和進(jìn)程的信號。在上圖中,Private Signal Queue是線程(在linux中稱為輕權(quán)進(jìn)程)信號隊列,而Shared Signal Queue是進(jìn)程(在linux中被稱為進(jìn)程組)信號隊列。對于進(jìn)程信號,則由進(jìn)程組中的每一個線程共享。例如,在上圖中,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是一個位圖,每一位表示一個對應(yīng)的信號,用于指示信號隊列中有哪些信號等待處理,其類型為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位,對應(yīng)64個信號位圖(32個普通信號和32個實(shí)時信號)。在以后的信號發(fā)送的分析中,我們會看到,對于普通信號,只需要把sigset_t中對應(yīng)的位置1就可以了,而對于實(shí)時信號,還需要把相關(guān)信息添加到list的信號隊列,信號隊列類型為sigqueue(include/linux/signal.h),定義如下:

      1. /*  
      2.  * Real Time signals may be queued.  
      3.   
      4. struct sigqueue {  
      5.     struct list_head list;  
      6.     spinlock_t *lock;  
      7.     int flags;  
      8.     siginfo_t info;  
      9.     struct user_struct *user;  
      10. };  
      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,對應(yīng)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)信息保存到對應(yīng)的sigantion結(jié)構(gòu)中。
      • 信號的發(fā)送:通過相關(guān)系統(tǒng)調(diào)用吧一個指定的信號發(fā)送到目標(biāo)進(jìn)程,如果該信號沒有被屏蔽,就把信號的相關(guān)信息添加到信號隊列中,如果有必要就喚醒目標(biāo)進(jìn)程。
      • 信號響應(yīng):進(jì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ā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多