Linux 對信號的總結

来源:https://www.cnblogs.com/XLX-0327/archive/2019/04/12/10697884.html
-Advertisement-
Play Games

Linux信號_總結 對信號本質的理解: 類似於中斷,區別在於中斷是由硬體產生的,而信號是由軟體實現的。 信號的來源: 觸發硬體(觸發鍵盤,或是硬體故障);軟體信號函數kill 、alarm、setitimer、sigqueue 等函數。 信號的分類: 可靠信號與不可靠信號,實時信號與非實時信號; ...


Linux信號_總結

對信號本質的理解:

類似於中斷,區別在於中斷是由硬體產生的,而信號是由軟體實現的。

信號的來源:

觸發硬體(觸發鍵盤,或是硬體故障);軟體信號函數kill 、alarm、setitimer、sigqueue 等函數。

信號的分類:

可靠信號與不可靠信號,實時信號與非實時信號;

不可靠信號:

SIGRTMIN前的信號稱為不可靠信號,在早期這段信號可能做出錯誤的反應,或是丟失。因此對此段信號成為不可靠信號。

可靠信號:

在SIGRTMIN與SIGRTMAX之間的信號稱做可靠信號,可靠信號是為了防止信號丟失的。這些信號可以排隊處理。

實時信號與非實時信號:

非實時信號都不支持排隊,都是不可靠信號;實時信號都是支持排隊的,都是可靠信號;

對信號的響應:

響應的三種方式

(1)忽略信號

有兩個特殊的信號SIGKILL 和SIGSTOP信號不能被忽略。

(2)捕捉信號

給對應的信號綁定響應的處理函數,帶到信號產生時,執行對應的函數。

(3)執行預設信號

進程對實時信號的預設反應時進程的終止。

信號的發送:

發送信號的函數有,kill(), alarm(),raise(),setitimer();

(1)kill(int pid, int signal);

PID參數信號的就收進程
pid>0 進程的ID為pid的進程
pid=0 同一個進程組
pid<0 && pid!=-1 進程組ID為pid絕對值的所有進程
pid=-1 發送至所有ID大於1的進程

參數介紹:

pid為進程號,singnal為信號值。

kill常用於pid>0的信號處理,調用成功返回0,否則返回-1。

(2)alarm(unsigned int seconds)

專門為SIGALRM信號而設函數,seconds表示時間,此函數意味著在seconds秒後向SIGALRM信號發送消息。

進程調用alarm後,以前的alarm()調用都將無效。若調用alarm()前,進程中已經設置了鬧鐘,則返回上一個鬧鐘生於的時間,否則返回0;

eg:

#include<signal.h>
#include<stdio.h>
int main(void)
{
printf("first time return:%d\n",alarm(4));
sleep(1);
printf("after sleep(1),remain:%d\n",alarm(2));
printf("renew alarm,remain:%d\n",alarm(1));
}

//運行結果為
first time return:0
after sleep(1),remain:3
renew alarm,remain:2

(3)raise(int signal);

此函數時向本進程發送signal信號的,signal為即將發送的信號值。調用成功返回0;否則返回 -1。

(4)setitimer()函數

int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));

結構體介紹:

struct itimerval 
{
 struct timeval it_interval;//間隔時間
 struct timeval it_value; //初始時間
 };  

struct timeval
{
   long tv_sec; //秒
   long tv_usec; //微妙
};            

參數描述:

which:表示定時器類型,setitimer有三種定時器類型。

ITIMER_REAL : 以系統真實的時間來計算,它送出SIGALRM信號。  

ITIMER_VIRTUAL : 設定程式執行時間;經過指定的時間後,內核將發送SIGVTALRM信號給本進程;

ITIMER_PROF : 設定進程執行以及內核因本進程而消耗的時間和,經過指定的時間後,內核將發送ITIMER_VIRTUAL信號給本進程;

it_interval指定間隔時間,it_value指定初始定時時間。如果只指定it_value,就是實現一次定時;如果同時指定 it_interval,則超時後,系統會重新初始化it_value為it_interval,實現重覆定時;

eg:

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>

void sigroutine(int signo) {
       switch (signo) {
               case SIGALRM:
                       printf("Catch a signal -- SIGALRM\n");
                       break;
               case SIGVTALRM:
                       printf("Catch a signal -- SIGVTALRM\n");
                       break;
      }
}

int main(int argc, char ** argv) {
       struct itimerval value,ovalue,value2;

       printf("process id is %d\n",getpid());
       signal(SIGALRM, sigroutine); //為SIGALRM信號綁定sigroutine函數
       signal(SIGVTALRM, sigroutine); //為SIGVTALRM信號綁定sigroutine函數

       value.it_value.tv_sec = 1;//設定起始時間
       value.it_value.tv_usec = 0;
       value.it_interval.tv_sec = 1;//設定終止時間
       value.it_interval.tv_usec = 0;
       setitimer(ITIMER_REAL, &value, &ovalue);

       value2.it_value.tv_sec = 0;
       value2.it_value.tv_usec = 500000;
       value2.it_interval.tv_sec = 0;
       value2.it_interval.tv_usec = 500000;
       setitimer(ITIMER_VIRTUAL, &value2, &ovalue);

       for (;;) ;
}

//運行結果為
process id is 3136
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM

安裝信號:

由signal()、sigaction()處理:

(1)signal(int signum, sighandler_t handler);

此函數的作用是,為handler函數,或處理過程綁定一個信號,每當出現信號後,進行handler處理。

signum:所指信號;

handler:處理過程,可以時函數的指針。這個也可設置為"SIG_IGN",表示忽略此信號,"SIG_DFL"表示以系統預設方式處理此信號。(註意:SIGKILL SIGSTOP不可被安裝)

此函數的例子可參考上一個例子。

(2)sigaction();

int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact));

signum:指定的信號(除SIGKILL,SIGSTOP外)

sigaction:指向結構指針,指定對特定信號的處理

oldact:指向的對象用來保存原來對相應信號的處理

sigaction()函數中第二個參數最為關鍵。

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

(1)結構體中的sa_restorer已經不使用可以忽略。

(2)sa_handler指定的處理函數只有一個參數類似於使用signal()函數

(3)sa_sigaction也是指定信號的處理函數,不過可以帶三個參數:

第一個參數為信號值;

第二個參數是指向siginfo_t結構的指針;

第三個參數沒有使用;

siginfo_t結構體如下:

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 */
  long     si_band;     /* Band event (was int in
                           glibc 2.3.2 and earlier) */
  int      si_fd;       /* File descriptor */
  short    si_addr_lsb; /* Least significant bit of address
                           (since Linux 2.6.32) */
};

(4)sa_mask指定在信號處理程式執行過程中,哪些信號應當被阻塞。預設情況下當前信號本身被阻塞,防止信號的嵌套發送,除非指定SA_NODEFER或者SA_NOMASK標誌位。

註:請註意sa_mask指定的信號阻塞的前提條件,是在由sigaction()安裝信號的處理函數執行過程中由sa_mask指定的信號才被阻塞。

(5)sa_flags標誌位:

當sa_flags設置為SA_SIGINFO時,示信號附帶的參數可以傳遞到信號處理函數中。即使sa_sigaction指定信號處理函數,如果不設置SA_SIGINFO,信號處理函數同樣不能得到信號傳遞過來的數據,在信號處理函數中對這些信息的訪問都將導致段錯誤。

信號,介紹先到此,如若覺得又不對的地方,請指出,共同進步謝謝!

參考博客有:

https://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html

http://www.cnblogs.com/dandingyy/articles/2653218.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在網上找了很多關於對象轉XML的,大多不支持匿名類轉換,今天在stackoverflow找了一篇文章 但是有些許BUG 已經修複 調用: 記得引入命名空間 ...
  • 在之前,紙殼CMS的主題僅僅只是CSS樣式,並不支持在主題下使用模板來構建不同的HTML結構。現在我們對主題功能做了增強,可以在主題下添加各自的模板,這樣在製作主題時,就會更加自由。不僅如此,新的主題引擎還允許替換系統中所有Action對應的視圖。 所以新的主題引擎可以修改包括後端在內的系統中的所有... ...
  • 距離上次入門篇時隔兩個月才出這進階篇,小編慚愧,對不住關註我的卡哇伊的小伙伴們,為此小編用這篇博來謝罪。 前面的準備工作我就不說了,註冊百度賬號api,創建web網站項目,引入動態鏈接庫引入。 不瞭解的童鞋可以花費10分鐘移步學習:https://www.cnblogs.com/xiongze520 ...
  • 1. LIS3DH管腳定義 PS:LIS3DH和mpu6050的X和Y方向是相反的, mpu6050如下圖所示: 2.LIS3DH加速度計介紹 由於LIS3DH只可以得到XYZ加速度,無法獲取角速度,所以LIS3DH是無法測出偏航角(yaw). 3. LIS3DH之轉換歐拉角介紹 3.1偏航角(ya ...
  • 昨天新安裝Linux,發現ping百度ping不通: 經查詢,得知是系統沒有配置DNS功能變數名稱伺服器,百度搜索DNS功能變數名稱伺服器列表: 編輯 /etc/resolv.conf 文件,添加查詢到的DNS伺服器: vi /etc/resolv.conf 添加DNS伺服器地址: nameserver 202.9 ...
  • 雲伺服器ESC 部署vsftpd服務 記一次ftp服務搭建的採坑過程,這個坑一直卡了很久時間,都給忘記了。最近由於公司項目需要部署FTP,經過各種採坑,終於把這個坑給填上了。廢話不多說,開乾 環境說明:阿裡雲伺服器(centos6系統) 1)安裝 vsftpd 服務 配置文件說明 2)配置 vsft ...
  • 伺服器的特性: 高速度的CPU運算能力 長時間的可靠運行 強大的I/O外部數據吞吐能力 伺服器通常具有更高的性能,效率,高可靠,高可用性,以及更好的擴展性。 伺服器的分類 (1)伺服器按外形分類 塔式伺服器: 常見的立式和卧式機箱結構的伺服器,可放置在普通的辦公環境。 優點:主板擴展性較強,適合常見 ...
  • 一. 原子操作的定義 原子操作,是指一組相關聯的操作要麼都不間斷的執行,要麼都不執行。 二. 原子操作對同步與互斥的意義 1. 討論原子操作的意義之前,先瞭解操作系統中如下概念: 競爭條件:兩個或多個進程或線程讀寫某些共用數據,而最後的結果取決於進程運行的精確時序,稱為競爭條件。 臨界區:把對共用內 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...