中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linux系統編程之進程間通信之淺談信號

發布時間:2020-06-27 23:18:54 來源:網絡 閱讀:1615 作者:捕風的xiao_k 欄目:編程語言

 我們接著談Linux學習過程中一個重要的話題--信號。


一、信號的概念:
       信號是一種軟件中斷,它提供了一種處理異步事件的方法,也是進程間唯一的異步通信方式。
二、信號的來源:
       1、硬件方式:
             當用戶按下終端上某些鍵時,將產生信號。
             硬件異常產生信號:除0操作、訪問非法空間……
       2、軟件方式
             用戶在終端下調用kill命令向進程發送任意信號
        進程調用kill或者sigqueue函數發送信號。
        當檢測到某種軟件條件發生時,如alarm或者setimer

 三、信號處理
        1、信號的捕捉和處理
              1、signal函數
                    a、函數作用:
                        signal函數用來設置進程在接收到信號時的動作。
                    b、函數原型:                  

              #include <signal.h>
         typedef void (*sighandler_t)(int);
         sighandler_t signal(int signum, sighandler_t handler);

                    c、參數解析與函數說明:
                              signal函數會根據參數signal指定的信號編號來設置該信號的處理函數。當指定的信號到達時就會

              跳到參數hander指定的函數執行。如果hander不是函數指針,則必須時常數SIG_IGN忽略該信號)或者S

              IG_DFL(對該信號執行默認操作)。hander是 一個函數指針,它所指向的函數的類型時sighandel_t,即

              它 所指向的函數有一個int型參數,且返回值的類型為void。
                    d、樣這里給出signal處理信號的例子:


/**********************************************************
*    > File Name: signal-1.c
*    > Author:xiao_k
*    > Mail:18629086235@163.com 
*    > Created Time: Fri 23 Feb 2018 12:05:46 AM CST
**********************************************************/
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<signal.h>
//信號處理函數
void do_sig(int num)
{
   printf("I am do_sig\n");
}
int main()
{
      //安裝處理信號
     signal(SIGINT,do_sig);
     while(1)
      {
        printf("********\n");
        sleep(1);
      }
       return 0;
 }

            2、sigaction函數
                 a、函數作用:
                       sigction函數可以用來檢查和設置進程在接收信號時的動作。
                 b、函數原型
                       #include <signal.h>
                       int sigaction(int signum, const struct sigaction *act,
                                                                 struct sigaction *oldact);
                 c、參數解析與函數說明:
                      sigzction函數會根據參數signum指定的信號編號來設置該信號的處理函數。參數signum可以是除了

           SIGKILLh和SIGSTOP以外的任何信號。
                如果參數act 不是空指針,則為signum設置新的信號處理函數;
                如果oldzct不是空指針,則舊的信號處理函數將被存儲在oldact中,struct sigaction的定義如下:     
                                    struct sigaction {
                                           void     (*sa_handler)(int);
                                           void     (*sa_sigaction)(int, siginfo_t *, void *);
                                           sigset_t   sa_mask;
                                           int        sa_flags;
                                           void     (*sa_restorer)(void);
                                   };
               sa_handler可以是常數SIG_DFL或者SIG_IGN,或者是一個信號處理函數名。
               sa_sigaction也是用來指定信號的signum的處理函數。
               sa_mask成員聲明了一個信號集,在調用信號捕捉函數之前,該信號會增加到進程的信號屏蔽碼中,

            新的信號屏蔽碼會自動包括正在處理的信號(sa_flags未指定SA_NODEFER或者SA_NOMASK)。當從信號捕

            捉函數返回時,進程的信號屏蔽碼會恢復為原來的值。因此,當處理一個給定的  信號時,如果這種

            信號再次發生,那么它會阻塞直到本次信號處理結束為止。若這種信號發生了多次,則對于不可靠信號,

            即本次信號處理結束以后只會再次處理一次(相當于丟失了信號),對于可靠信號(實時信號),則會

            被阻塞多次,即信號不會丟失,信號發生了多少次就會調用信號處理函數多少次。
               sa_flags成員用來說明信號處理的其他相關操作。         
               當使用三參數的sa_sigaction來指定信號處理函數時,它的第 二個參數可以用來傳遞數據,其定義

            如下:
                      siginfo_t {
                          int      si_signo;    /* Signal number */
                          int      si_errno;    /* An errno value */
                          int      si_code;     /* Signal code */
                          int      si_trapno;   /* Trap number that caused
                                         hardware-generated signal (unused on most architectures) */
                          pid_t    si_pid;      /* Sending process ID */
                          uid_t    si_uid;      /* Real user ID of sending process */
                          int      si_status;   /* Exit value or signal */
                          clock_t  si_utime;    /* User time consumed */
                          clock_t  si_stime;    /* System time consumed */
                          sigval_t si_value;    /* Signal value */
                          int      si_int;      /* POSIX.1b signal */
                          void    *si_ptr;      /* POSIX.1b signal */
                          int      si_overrun;  /* Timer overrun count;POSIX.1b timers */
                          int      si_timerid;  /* Timer ID; POSIX.1b timers */
                          void    *si_addr;     /* Memory location which caused fault */
                          int      si_band;     /* Band event */
                          int      si_fd;       /* File descriptor */
                                               }

                d、同樣給出 sigaction的測試用例

/**********************************************************
*    > File Name: sigaction-1.c
*    > Author:xiao_k
*    > Mail:18629086235@163.com 
*    > Created Time: Fri 23 Feb 2018 01:47:43 AM CST
**********************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<signal.h>
int temp = 0;
//信號處理函數
void do_sigact(int num)
{
    printf("recv SIGINT\n");
    sleep(5);
    temp +=1;
    printf("the value of temp is :%d\n",temp);
    printf("in do_sigact,after sleep\n");
}
int main()
  {
     struct sigaction act;
      //結構體賦值
      act.sa_handler = do_sigact;
      act.sa_flags = SA_NOMASK;
      //安裝信號處理函數
      sigaction(SIGINT,&act,NULL);
     while(1)
      {
        printf("********************\n");
        sleep(1);
      }
     return 0;
   }

            編寫信號處理函數時,要注意不要使用不可重入的函數,使用了不重入的函數將將產生不可預料的結果。

    上邊就是sigaction函數的基本用法,復雜的用法后邊使用。
                補充:滿足下列條件的函數是不可重入的:
                           a、使用了靜態的數據結構,如getgrpid(),全局變量等。  
                           b、函數實現時,調用了malloc()或者free()函數。
                           c、函數實現時,使用了標準I/O函數。


            3、pause()函數
                 a、函數作用:
                      pause函數使調用進程掛起直到捕捉到一個信號。pause函數會令目前的進程暫停(進入睡眠狀態),

          直到被信號(signal)所中斷,該函數只返回-1,并將errno設置為EINTR。
                 b、函數原型:
                       #include <unistd.h>
                       int pause(void);
四、信號的發送:
         信號的發送主要由函數kill、raise、sigqueue、alarm、setitimer以及 abort來完成。
         1、kill函數
               a、函數作用:
                   kill函數用來發送信號給指定的進程。
               b、函數原型      

       #include <sys/types.h>
       #include <signal.h>
       int kill(pid_t pid, int sig);

                c、參數解析與函數說明:
                     該函數的行為與第二個參數pid的取值有關,第二個參數sig表示信號編號:
                如果pid時正數,則發送信號sig給進程號為pid的進程;
                果pid為0,則發送信號sig給當前進程所屬進程組里的所有進程;
                如果pid為-1,則把信號sig廣播給系統內的除1號進程和自身以外的所有進程;
                如果pid為比-1還小的負數,則發送信號sig給屬于進程組-pid的所有進程;
                如果參數sig是0,則kill(),仍然執行正常的錯誤檢查,但不發送信號。可以利用這一點來確定某

            進程是否有權向另外一個進程發送信號。如果向一個并不存在的進程發送空信號,則kill()返回-1,

            errno則被設置為ESRCH。
            注意:只有具有root權限的進程才能向其他任意一個進程發送信號,非root權限的進程只能向屬于同一

               個組成或者同一個用戶創建的進程發送信號。
        2、raise函數
              a、函數作用:
                   raise函數是ANSI C 而非POSIX標準定義的。用來給調用它的進程發送信號。
              b、函數原型         

       #include <signal.h>
        int raise(int sig);

         3、sigqueue函數
                     a、函數作用
                          sigqueue函數是一個比較新的發送信號的函數,它支持信號帶有參數,從而可以與函數sigaction配

            合使用。
                     b、函數原型
                          #include <signal.h>
                          int sigqueue(pid_t pid, int sig, const union sigval value);
                     c、參數解析與函數說明:
                            sigqueue用來發送給信號sig給進程pid。與kill系統調用不同的是,sigqueue在發送信號的同時

             還支持信號攜帶參數;另外一個不同點是sigqueue 不能給一組進程發送信號,參數value是一個共用
             體,其定義如下:
                            union sigval {
                               int   sival_int;
                               void *sival_ptr;
                                      };

     4、alarm函數
           a、函數作用
              alarm函數可以用來設置定時器,定時器超時將產生SIGALRM信號給調用進程。
           b、函數原型                 

         #include <unistd.h>
      unsigned int alarm(unsigned int seconds);

           c、參數解析與函數說明:
                參數seconds表示設定的秒數,經過seconds后,內核將給調用該函數的進程發送SIGALRM信號。如果seconds為0,

      則不再發送SIGALRM信號,最新一次調用alarm函數將取消之前一次的設定。  
     5、abrot函數
            a、函數作用:
                abrot函數用來向進程發送SIGABRT信號。
            b、函數原型             

      #include <stdlib.h>
     void abort(void)

      上邊我只對信號的基本用法做了總結,后邊將對信號的高級用法做單獨總結。



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

汪清县| 佳木斯市| 黑山县| 峨边| 宁河县| 武清区| 太仆寺旗| 香格里拉县| 福建省| 宁晋县| 合川市| 新巴尔虎右旗| 高碑店市| 惠水县| 镇宁| 卫辉市| 志丹县| 涿鹿县| 南城县| 普宁市| 禄丰县| 四平市| 方正县| 常山县| 宿松县| 依安县| 呼伦贝尔市| 常德市| 中山市| 鹿邑县| 高阳县| 清镇市| 蓝山县| 吴江市| 察隅县| 娄底市| 肥东县| 甘泉县| 桐乡市| 南丹县| 辽阳县|