• <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
            數(shù)據(jù)加載中……

            signal 轉(zhuǎn)貼的,不知來源,見諒

            信號是進程之間通信的另外一種方式。之前用過kill -l看了Linux系統(tǒng)支持的所有信號,這些信號在sys/signal.h中定義,系統(tǒng)支持64種信號。除了系統(tǒng)內(nèi)核和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、信號的產(chǎn)生

            (1)kill函數(shù)

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

            函數(shù)執(zhí)行成功返回0,失敗返回-1.

            (2)raise函數(shù)

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

            函數(shù)執(zhí)行成功返回0,失敗返回非零數(shù)值。

            (3)alarm函數(shù)

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

            【程序?qū)嵗?/p>

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

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

            #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;

            }

            執(zhí)行結(jié)果:

            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對應(yīng)信號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、信號的處理

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

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

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

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

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

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

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

            下面signal函數(shù)和sigaction函數(shù)是Linux提供的2個系統(tǒng)調(diào)用。

             

            (1)signal函數(shù)

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

            typedef void (*sighandler_t)(int);

            signum:要捕獲的信號值;

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

            【程序?qū)嵗?/p>

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

            #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;
            }

            執(zhí)行結(jié)果:

            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函數(shù)

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

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

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

            ---act:如果act非空,則按照act指向的結(jié)構(gòu)體信息重新設(shè)置信號處理函數(shù);

            ---oldact:如果oldact非空,將原有的信號處理函數(shù)保存在oldact指向的結(jié)構(gòu)體。

            sigaction結(jié)構(gòu)體定義和參數(shù)取值略。。。

            【程序?qū)嵗?/p>

            下面的程序打印信號1-11的處理方式,由于只有信號10(SIGUSR1)的默認處理方式被函數(shù)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:捕獲信號完成處理后,將信號處理恢復(fù)為默認處理;SA_NODEFER:完成信號處理之前如果再次收到信號,不做處理

             sigaction(SIGUSR1,&act,&oldact);  //對信號SIGUSR1更改默認處理方式,處理調(diào)用函數(shù)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;
            }

            執(zhí)行結(jié)果:

            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系統(tǒng)而言,不可靠信號的含義有2個:

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

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

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

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

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

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

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


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            久久久久亚洲精品无码蜜桃| 久久精品国产AV一区二区三区| 日韩十八禁一区二区久久| 亚洲精品无码久久久久| 18禁黄久久久AAA片| 亚洲AV伊人久久青青草原| 国产精品欧美亚洲韩国日本久久 | 性做久久久久久久久浪潮| 香港aa三级久久三级| 国产精品久久久久乳精品爆| 狠狠色伊人久久精品综合网| 国产午夜福利精品久久| 国产高清国内精品福利99久久| 国产高潮久久免费观看| 三级片免费观看久久| 精品伊人久久大线蕉色首页| 久久亚洲精品人成综合网 | 国内精品久久久久久久97牛牛 | 亚洲综合精品香蕉久久网| 国产精品久久久亚洲| 久久这里只有精品首页| 久久本道久久综合伊人| 国产99久久久国产精品小说| 久久久亚洲欧洲日产国码二区| 狠狠色丁香婷综合久久| 久久久久亚洲av毛片大| 国内高清久久久久久| 97久久国产亚洲精品超碰热| 久久久久国产成人精品亚洲午夜| 国产精品久久久久久久久软件 | 国产精品永久久久久久久久久| 欧美久久久久久| 99久久99久久| 久久人人爽人人爽人人片AV东京热| 高清免费久久午夜精品| 久久久久国色AV免费看图片| 久久99国产精品尤物| 久久久WWW成人免费精品| 国产国产成人精品久久| 97精品依人久久久大香线蕉97 | 国内精品久久久久国产盗摄|