• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            輕重緩急

            成功來源于有效的自我管理。
            隨筆 - 14, 文章 - 3, 評論 - 3, 引用 - 0
            數據加載中……

            signal 轉貼的,不知來源,見諒

            信號是進程之間通信的另外一種方式。之前用過kill -l看了Linux系統支持的所有信號,這些信號在sys/signal.h中定義,系統支持64種信號。除了系統內核和root之外,只有具備相同uid、gid的進程才可以使用信號進行通信。

            gaolu@gaolu-desktop:~$ kill -l
             1) SIGHUP  2) SIGINT  3) SIGQUIT  4) SIGILL
             5) SIGTRAP  6) SIGABRT  7) SIGBUS  8) SIGFPE
             9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
            13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT   //本次程序提到信號
            17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
            21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU
            25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH
            29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN
            35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4
            39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
            43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
            47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
            51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
            55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6
            59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
            63) SIGRTMAX-1 64) SIGRTMAX 
            gaolu@gaolu-desktop:~$

            1、信號的產生

            (1)kill函數

            函數調用形式為int kill(pid_t pid,int sig),表示向進程pid發送信號sig。這個函數之前用過,不再介紹。

            函數執行成功返回0,失敗返回-1.

            (2)raise函數

            該函數用于給調用進程自身發送信號,調用形式為int raise(int sig);等同與調用kill(getpid(),sig).

            函數執行成功返回0,失敗返回非零數值。

            (3)alarm函數

            該函數用于給進程設置告警時鐘,時鐘(單位為秒)到達后,給進程發送SIGALARM信號。默認處理方式為進程直接終止運行,也可以修改捕捉信號后的默認處理函數。

            【程序實例】

            //連續創建5個子進程,分別給5個子進程設置告警時鐘1-5秒,時鐘到達時,捕捉到SIGALARM信號,采用默認處理方式,直接終止執行;捕捉到信號之前用pause掛起進程,使其處于等待狀態;由于捕捉信號以后的默認處理就是終止,因此不需要顯式的調用_exit等函數。

            父進程等待所有的子進程結束,根據wait到的status,調用宏判斷是屬于正常退出(打印退出碼),還是接受到信號退出(打印接收到的信號值)。

            #include <stdio.h>
            #include <unistd.h>
            #include <sys/types.h>
            #include <sys/wait.h>

            int main(void)
            {
             int status,i;
             pid_t pid,wait_pid;

             for(i=1;i<=5;i++)
             {
              pid = fork();
              if(pid<0)
              {
               perror("Creat child process failed.\n");
               return 1;
              }
              if(pid == 0)
              {
               printf("Child process %ld will terminal after %d seconds.\n",(long)getpid(),i);
               alarm(i);
               pause();
              }
             }
             
             while((pid = wait(&status))&&pid!=-1)
             {
              if(WIFSIGNALED(status))
              {
               printf("Process %d exit because of receiving signal %d.\n",pid,WTERMSIG(status));
              }
              if(WIFEXITED(status))
              {
               printf("Process %d exit code %d.\n",pid,WEXITSTATUS(status));
              }
             }
             return 0;

            }

            執行結果:

            gaolu@gaolu-desktop:~$
            gaolu@gaolu-desktop:~$ gcc -o sig systemcall2.c
            gaolu@gaolu-desktop:~$ ./sig
            Child process 5757 will terminal after 1 seconds.
            Child process 5758 will terminal after 2 seconds.
            Child process 5759 will terminal after 3 seconds.
            Child process 5760 will terminal after 4 seconds.
            Child process 5761 will terminal after 5 seconds.
            Process 5757 exit because of receiving signal 14.   //14對應信號SIGALRM 
            Process 5758 exit because of receiving signal 14.
            Process 5759 exit because of receiving signal 14.
            Process 5760 exit because of receiving signal 14.
            Process 5761 exit because of receiving signal 14.
            gaolu@gaolu-desktop:~$

             

            2、信號的處理

            進程捕捉到信號以后可以有三種處理方式:

            ---不做任何處理(采用系統默認的處理方式);

            ---忽略信號(需要修改默認處理到ignore);

            ---捕獲信號(需要修改默認處理到自定義的處理方式);

            *******************************************

            SIGKILL和SIGSTOP是不能夠被捕獲的。

            *******************************************

            下面signal函數和sigaction函數是Linux提供的2個系統調用。

             

            (1)signal函數

            調用形式sighandler_t signal(int signum,sighandler_t handler);

            typedef void (*sighandler_t)(int);

            signum:要捕獲的信號值;

            handler:指向要調用的函數指針(可以為SIG_IGN忽略信號或者為SIG_DFL采用默認方式);

            【程序實例】

            代碼中修改了對SIGINT的處理方式,默認為直接終止,修改成為忽略信號;對于SIGUSR1,調用函數sigusr1 進行處理后結束。

            #include <stdio.h>
            #include <unistd.h>
            #include <signal.h>
            #include <stdlib.h>

            void sigusr1 (int sig)
            {
             printf("Get the SIGUSER signal,now process...\n");


             exit(0);
            }

            int main (void)
            {
             if(signal(SIGINT,SIG_IGN)==SIG_ERR)
             {
              printf("Fail to reset signal handler of SIGINT.\n");
              return 1;
             }
             if(signal(SIGUSR1,sigusr1)==SIG_ERR)
             {
              printf("Fail to reset signal handler of SIGUSR1.\n");
              return 1;
             }
             pause();
             return 0;
            }

            執行結果:

            gaolu@gaolu-desktop:~$
            gaolu@gaolu-desktop:~$
            gaolu@gaolu-desktop:~$ gcc -o sig systemcall2.c
            gaolu@gaolu-desktop:~$ ./sig &
            [1] 6011
            gaolu@gaolu-desktop:~$ kill -SIGINT 6011
            gaolu@gaolu-desktop:~$ jobs
            [1]+  Running                 ./sig &      //SIGINT被忽略了
            gaolu@gaolu-desktop:~$ kill -SIGUSR1 6011
            Get the SIGUSER signal,now process...
            [1]+  Done                    ./sig
            gaolu@gaolu-desktop:~$
            gaolu@gaolu-desktop:~$
            gaolu@gaolu-desktop:~$ jobs
            gaolu@gaolu-desktop:~$

             

            (2)sigaction函數

            該函數用于檢查或者指定信號的處理動作。

            調用形式int sigaction(int signum,const struct sigaction *act,const struct sigaction *oldact);

            ---signum:要捕捉的信號值(不包括SIGKILL和SIGSTOP);

            ---act:如果act非空,則按照act指向的結構體信息重新設置信號處理函數;

            ---oldact:如果oldact非空,將原有的信號處理函數保存在oldact指向的結構體。

            sigaction結構體定義和參數取值略。。。

            【程序實例】

            下面的程序打印信號1-11的處理方式,由于只有信號10(SIGUSR1)的默認處理方式被函數sigaction修改過,其他的打印都為默認處理SIG_DFL.

            #include <stdio.h>
            #include <signal.h>

            void signal_process_info(struct sigaction *act)
            {
             switch(act->sa_flags)
             {
              case (int)SIG_DFL:
              {
               printf("using default handler.\n");
               break;
              }
              case (int)SIG_IGN:
              {
               printf("ignore the signal.\n");
               break;
              }
              default:
              {
               printf("use handler: %0x.\n",act->sa_flags);
               break;
              }
             }
             return;
            }

            void usr1_handler(void)
            {
             
            }

            int main(void)
            {
             int i;
             struct sigaction act,oldact;

             act.sa_handler =  usr1_handler;
             act.sa_flags = SA_NODEFER|SA_RESETHAND;  //SA_RESETHAND:捕獲信號完成處理后,將信號處理恢復為默認處理;SA_NODEFER:完成信號處理之前如果再次收到信號,不做處理

             sigaction(SIGUSR1,&act,&oldact);  //對信號SIGUSR1更改默認處理方式,處理調用函數usr1_handler

             for(i=1;i<12;i++)
             {
              printf("signal %d handler is:",i);
              sigaction(i,NULL,&oldact); //act=NULL,檢查而已
              signal_process_info(&oldact); //打印信號處理方式
             }
             return 0;
            }

            執行結果:

            gaolu@gaolu-desktop:~$
            gaolu@gaolu-desktop:~$ gcc -o sig2 systemcall2.c
            systemcall2.c: In function main
            systemcall2.c:37: warning: assignment from incompatible pointer type
            gaolu@gaolu-desktop:~$
            gaolu@gaolu-desktop:~$
            gaolu@gaolu-desktop:~$
            gaolu@gaolu-desktop:~$
            gaolu@gaolu-desktop:~$ ./sig2
            signal 1 handler is:using default handler.
            signal 2 handler is:using default handler.
            signal 3 handler is:using default handler.
            signal 4 handler is:using default handler.
            signal 5 handler is:using default handler.
            signal 6 handler is:using default handler.
            signal 7 handler is:using default handler.
            signal 8 handler is:using default handler.
            signal 9 handler is:using default handler.
            signal 10 handler is:use handler: c0000000.
            signal 11 handler is:using default handler.
            gaolu@gaolu-desktop:~$
            *************************************************************************************

            信號值小于SIGRTMIN的信號都是不可靠信號。對于UNIX系統而言,不可靠信號的含義有2個:

            (1)可能對信號采用錯誤的處理

            捕捉到不可靠信號并處理以后,可能將信號的處理方法恢復到系統默認的處理方法。因此每次處理以后,都要重新設置信號處理函數。

            (2)存在信號丟失的可能

            比如sleep()或者pause()時可能捕捉不到信號。

            在Linux系統下,不可靠信號僅指信號的丟失,因為系統對不可靠信號機制做了改進,不需要重新設置信號處理函數。

            考慮到代碼的可移植性,使用較多的是sigaction()函數。

            posted on 2010-04-16 17:34 隨遇而安 閱讀(273) 評論(0)  編輯 收藏 引用

            伊人色综合久久天天人守人婷| 久久男人AV资源网站| 一本一本久久A久久综合精品 | 色综合久久中文综合网| 99久久精品九九亚洲精品| 亚洲国产精品综合久久网络| 亚洲人成精品久久久久| 久久夜色tv网站| 久久久国产打桩机| 狠狠人妻久久久久久综合蜜桃| 免费无码国产欧美久久18| 999久久久无码国产精品| 久久久久99这里有精品10 | 综合网日日天干夜夜久久| 一本一道久久精品综合| 久久国语露脸国产精品电影| 国产视频久久| 亚洲va久久久噜噜噜久久天堂| 精品99久久aaa一级毛片| 996久久国产精品线观看| 久久人人爽人人人人爽AV| 久久精品成人一区二区三区| 久久精品国产亚洲av影院| 免费精品久久天干天干| 欧美伊人久久大香线蕉综合69| 久久久久国产一级毛片高清版| 中文字幕无码精品亚洲资源网久久| 99热成人精品免费久久| 国产成人久久激情91| 国内精品伊人久久久久av一坑| 国产成人无码精品久久久性色| 青青热久久国产久精品 | 久久人人爽爽爽人久久久| 思思久久99热只有频精品66| 久久99精品国产麻豆不卡| 狠狠久久综合| 青春久久| 国产麻豆精品久久一二三| 国产精品久久久久久| 久久久精品免费国产四虎| 成人精品一区二区久久|